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