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: [email protected]
For additional commands, e-mail: [email protected]