You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2013/09/03 11:24:08 UTC

svn commit: r1519611 - in /tomcat/trunk/java/org/apache/coyote/ajp: AbstractAjpProcessor.java AjpAprProcessor.java AjpNioProcessor.java AjpProcessor.java

Author: markt
Date: Tue Sep  3 09:24:08 2013
New Revision: 1519611

URL: http://svn.apache.org/r1519611
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=55500
Ensure async timeout is applied when using Servlet 3.0 async with the AJP NIO connector.

Modified:
    tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java
    tomcat/trunk/java/org/apache/coyote/ajp/AjpAprProcessor.java
    tomcat/trunk/java/org/apache/coyote/ajp/AjpNioProcessor.java
    tomcat/trunk/java/org/apache/coyote/ajp/AjpProcessor.java

Modified: tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java?rev=1519611&r1=1519610&r2=1519611&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java (original)
+++ tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java Tue Sep  3 09:24:08 2013
@@ -473,6 +473,10 @@ public abstract class AbstractAjpProcess
             asyncStateMachine.asyncStart((AsyncContextCallback) param);
         } else if (actionCode == ActionCode.ASYNC_DISPATCHED) {
             asyncStateMachine.asyncDispatched();
+        } else if (actionCode == ActionCode.ASYNC_SETTIMEOUT) {
+            if (param == null) return;
+            long timeout = ((Long)param).longValue();
+            socketWrapper.setTimeout(timeout);
         } else if (actionCode == ActionCode.ASYNC_TIMEOUT) {
             AtomicBoolean result = (AtomicBoolean) param;
             result.set(asyncStateMachine.asyncTimeout());
@@ -556,6 +560,7 @@ public abstract class AbstractAjpProcess
         try {
             rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE);
             error = !getAdapter().asyncDispatch(request, response, status);
+            resetTimeouts();
         } catch (InterruptedIOException e) {
             error = true;
         } catch (Throwable t) {
@@ -806,6 +811,18 @@ public abstract class AbstractAjpProcess
     // Methods called by action()
     protected abstract void actionInternal(ActionCode actionCode, Object param);
 
+    // Methods called by asyncDispatch
+    /**
+     * Provides a mechanism for those connector implementations (currently only
+     * NIO) that need to reset timeouts from Async timeouts to standard HTTP
+     * timeouts once async processing completes.
+     */
+    protected abstract void resetTimeouts();
+
+    // Methods called by prepareResponse()
+    protected abstract void output(byte[] src, int offset, int length)
+            throws IOException;
+
     // Methods called by process()
     protected abstract void setupSocket(SocketWrapper<S> socketWrapper)
             throws IOException;
@@ -813,10 +830,6 @@ public abstract class AbstractAjpProcess
     protected abstract void setTimeout(SocketWrapper<S> socketWrapper,
             int timeout) throws IOException;
 
-    // Methods called by prepareResponse()
-    protected abstract void output(byte[] src, int offset, int length)
-            throws IOException;
-
     // Methods used by readMessage
     /**
      * Read at least the specified amount of bytes, and place them

Modified: tomcat/trunk/java/org/apache/coyote/ajp/AjpAprProcessor.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ajp/AjpAprProcessor.java?rev=1519611&r1=1519610&r2=1519611&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/ajp/AjpAprProcessor.java (original)
+++ tomcat/trunk/java/org/apache/coyote/ajp/AjpAprProcessor.java Tue Sep  3 09:24:08 2013
@@ -89,10 +89,7 @@ public class AjpAprProcessor extends Abs
                 ((AprEndpoint)endpoint).processSocketAsync(this.socketWrapper,
                         SocketStatus.OPEN_READ);
             }
-        } else if (actionCode == ActionCode.ASYNC_SETTIMEOUT) {
-            if (param == null) return;
-            long timeout = ((Long)param).longValue();
-            socketWrapper.setTimeout(timeout);
+
         } else if (actionCode == ActionCode.ASYNC_DISPATCH) {
             if (asyncStateMachine.asyncDispatch()) {
                 ((AprEndpoint)endpoint).processSocketAsync(this.socketWrapper,
@@ -103,6 +100,13 @@ public class AjpAprProcessor extends Abs
 
 
     @Override
+    protected void resetTimeouts() {
+        // NO-OP. The AJP APR/native connector only uses the timeout value on
+        //        time SocketWrapper for async timeouts.
+    }
+
+
+    @Override
     protected void setupSocket(SocketWrapper<Long> socketWrapper) {
         long socketRef = socketWrapper.getSocket().longValue();
         Socket.setrbb(socketRef, inputBuffer);

Modified: tomcat/trunk/java/org/apache/coyote/ajp/AjpNioProcessor.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ajp/AjpNioProcessor.java?rev=1519611&r1=1519610&r2=1519611&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/ajp/AjpNioProcessor.java (original)
+++ tomcat/trunk/java/org/apache/coyote/ajp/AjpNioProcessor.java Tue Sep  3 09:24:08 2013
@@ -26,7 +26,6 @@ import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
 import org.apache.tomcat.util.net.NioChannel;
 import org.apache.tomcat.util.net.NioEndpoint;
-import org.apache.tomcat.util.net.NioEndpoint.KeyAttachment;
 import org.apache.tomcat.util.net.NioSelectorPool;
 import org.apache.tomcat.util.net.SocketStatus;
 import org.apache.tomcat.util.net.SocketWrapper;
@@ -74,14 +73,7 @@ public class AjpNioProcessor extends Abs
                 ((NioEndpoint)endpoint).dispatchForEvent(
                         socketWrapper.getSocket(), SocketStatus.OPEN_READ, true);
             }
-        } else if (actionCode == ActionCode.ASYNC_SETTIMEOUT) {
-            if (param == null) return;
-            long timeout = ((Long)param).longValue();
-            final KeyAttachment ka =
-                    (KeyAttachment)socketWrapper.getSocket().getAttachment(false);
-            if (keepAliveTimeout > 0) {
-                ka.setTimeout(timeout);
-            }
+
         } else if (actionCode == ActionCode.ASYNC_DISPATCH) {
             if (asyncStateMachine.asyncDispatch()) {
                 ((NioEndpoint)endpoint).dispatchForEvent(
@@ -92,6 +84,27 @@ public class AjpNioProcessor extends Abs
 
 
     @Override
+    protected void resetTimeouts() {
+        // The NIO connector uses the timeout configured on the wrapper in the
+        // poller. Therefore, it needs to be reset once asycn processing has
+        // finished.
+        final NioEndpoint.KeyAttachment attach = (NioEndpoint.KeyAttachment)socketWrapper.getSocket().getAttachment(false);
+        if (!error && attach != null &&
+                asyncStateMachine.isAsyncDispatching()) {
+            long soTimeout = endpoint.getSoTimeout();
+
+            //reset the timeout
+            if (keepAliveTimeout > 0) {
+                attach.setTimeout(keepAliveTimeout);
+            } else {
+                attach.setTimeout(soTimeout);
+            }
+        }
+
+    }
+
+
+    @Override
     protected void setupSocket(SocketWrapper<NioChannel> socketWrapper)
             throws IOException {
         // NO-OP

Modified: tomcat/trunk/java/org/apache/coyote/ajp/AjpProcessor.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ajp/AjpProcessor.java?rev=1519611&r1=1519610&r2=1519611&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/ajp/AjpProcessor.java (original)
+++ tomcat/trunk/java/org/apache/coyote/ajp/AjpProcessor.java Tue Sep  3 09:24:08 2013
@@ -86,11 +86,7 @@ public class AjpProcessor extends Abstra
                 ((JIoEndpoint)endpoint).processSocketAsync(this.socketWrapper,
                         SocketStatus.OPEN_READ);
             }
-        } else if (actionCode == ActionCode.ASYNC_SETTIMEOUT) {
-            if (param == null) return;
-            long timeout = ((Long)param).longValue();
-            // if we are not piggy backing on a worker thread, set the timeout
-            socketWrapper.setTimeout(timeout);
+
         } else if (actionCode == ActionCode.ASYNC_DISPATCH) {
             if (asyncStateMachine.asyncDispatch()) {
                 ((JIoEndpoint)endpoint).processSocketAsync(this.socketWrapper,
@@ -101,6 +97,13 @@ public class AjpProcessor extends Abstra
 
 
     @Override
+    protected void resetTimeouts() {
+        // NO-OP. The AJP BIO connector only uses the timeout value on the
+        //        SocketWrapper for async timeouts.
+    }
+
+
+    @Override
     protected void setupSocket(SocketWrapper<Socket> socketWrapper)
             throws IOException {
         input = socketWrapper.getSocket().getInputStream();



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