Author: markt
Date: Tue May 25 13:53:14 2010
New Revision: 948043

URL: http://svn.apache.org/viewvc?rev=948043&view=rev
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=49095
AprEndpoint does not wakeup accepts with deferred accept or BSD filters
Based on a patch provided by Ruediger Pluem

Modified:
    tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java?rev=948043&r1=948042&r2=948043&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java Tue May 25 
13:53:14 2010
@@ -17,6 +17,8 @@
 
 package org.apache.tomcat.util.net;
 
+import java.io.PrintWriter;
+import java.net.InetSocketAddress;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.ArrayList;
@@ -578,6 +580,59 @@ public class AprEndpoint extends Abstrac
 
 
     /**
+     * Unlock the server socket accept using a bogus connection.
+     */
+    @Override
+    protected void unlockAccept() {
+        java.net.Socket s = null;
+        InetSocketAddress saddr = null;
+        try {
+            // Need to create a connection to unlock the accept();
+            if (getAddress() == null) {
+                saddr = new InetSocketAddress("localhost", getPort());
+            } else {
+                saddr = new InetSocketAddress(getAddress(),getPort());
+            }
+            s = new java.net.Socket();
+            s.setSoTimeout(getSocketProperties().getSoTimeout());
+            // TODO Consider hard-coding to s.setSoLinger(true,0)
+            
s.setSoLinger(getSocketProperties().getSoLingerOn(),getSocketProperties().getSoLingerTime());
+            if (log.isDebugEnabled()) {
+                log.debug("About to unlock socket for:"+saddr);
+            }
+            s.connect(saddr,getSocketProperties().getUnlockTimeout());
+            /*
+             * In the case of a deferred accept / accept filters we need to
+             * send data to wake up the accept. Send OPTIONS * to bypass even
+             * BSD accept filters. The Acceptor will discard it.
+             */
+            if (deferAccept) {
+                PrintWriter pw;
+
+                pw = new PrintWriter(s.getOutputStream());
+                pw.print("OPTIONS * HTTP/1.0\r\n" +
+                         "User-Agent: Tomcat wakeup connection\r\n\r\n");
+                pw.flush();
+            }
+            if (log.isDebugEnabled()) {
+                log.debug("Socket unlock completed for:"+saddr);
+            }
+        } catch(Exception e) {
+            if (log.isDebugEnabled()) {
+                log.debug(sm.getString("endpoint.debug.unlock", "" + 
getPort()), e);
+            }
+        } finally {
+            if (s != null) {
+                try {
+                    s.close();
+                } catch (Exception e) {
+                    // Ignore
+                }
+            }
+        }
+    }    
+
+    /**
      * Pause the endpoint, which will make it stop accepting new sockets.
      */
     @Override
@@ -823,6 +878,15 @@ public class AprEndpoint extends Abstrac
                 try {
                     // Accept the next incoming connection from the server 
socket
                     long socket = Socket.accept(serverSock);
+                    /*
+                     * In the case of a deferred accept unlockAccept needs to
+                     * send data. This data will be rubbish, so destroy the
+                     * socket and don't process it.
+                     */
+                    if (deferAccept && (paused || !running)) {
+                        Socket.destroy(socket);
+                        continue;
+                    }
                     // Hand this socket off to an appropriate processor
                     if (!processSocketWithOptions(socket)) {
                         // Close socket and pool right away



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to