Author: markt Date: Tue Sep 3 09:38:04 2013 New Revision: 1519616 URL: http://svn.apache.org/r1519616 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/tc7.0.x/trunk/ (props changed) tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AjpAprProcessor.java tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AjpNioProcessor.java tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AjpProcessor.java tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Propchange: tomcat/tc7.0.x/trunk/ ------------------------------------------------------------------------------ Merged /tomcat/trunk:r1519611 Modified: tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java?rev=1519616&r1=1519615&r2=1519616&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java Tue Sep 3 09:38:04 2013 @@ -481,6 +481,7 @@ public abstract class AbstractAjpProcess try { rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE); error = !adapter.asyncDispatch(request, response, status); + resetTimeouts(); } catch (InterruptedIOException e) { error = true; } catch (Throwable t) { @@ -598,10 +599,21 @@ 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 used by SocketInputBuffer protected abstract boolean receive() throws IOException; Modified: tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AjpAprProcessor.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AjpAprProcessor.java?rev=1519616&r1=1519615&r2=1519616&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AjpAprProcessor.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AjpAprProcessor.java Tue Sep 3 09:38:04 2013 @@ -263,10 +263,12 @@ public class AjpAprProcessor extends Abs ((AprEndpoint)endpoint).processSocketAsync(this.socket, SocketStatus.OPEN_READ); } + } else if (actionCode == ActionCode.ASYNC_SETTIMEOUT) { if (param == null) return; long timeout = ((Long)param).longValue(); socket.setTimeout(timeout); + } else if (actionCode == ActionCode.ASYNC_DISPATCH) { if (asyncStateMachine.asyncDispatch()) { ((AprEndpoint)endpoint).processSocketAsync(this.socket, @@ -276,7 +278,11 @@ public class AjpAprProcessor extends Abs } - // ------------------------------------------------------ Protected Methods + @Override + protected void resetTimeouts() { + // NO-OP. The AJP APR/native connector only uses the timeout value on + // time SocketWrapper for async timeouts. + } @Override Modified: tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AjpNioProcessor.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AjpNioProcessor.java?rev=1519616&r1=1519615&r2=1519616&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AjpNioProcessor.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AjpNioProcessor.java Tue Sep 3 09:38:04 2013 @@ -255,13 +255,13 @@ public class AjpNioProcessor extends Abs ((NioEndpoint)endpoint).processSocket(this.socket, SocketStatus.OPEN_READ, false); } + } else if (actionCode == ActionCode.ASYNC_SETTIMEOUT) { if (param == null) return; long timeout = ((Long)param).longValue(); final KeyAttachment ka = (KeyAttachment)socket.getAttachment(false); - if (keepAliveTimeout > 0) { - ka.setTimeout(timeout); - } + ka.setTimeout(timeout); + } else if (actionCode == ActionCode.ASYNC_DISPATCH) { if (asyncStateMachine.asyncDispatch()) { ((NioEndpoint)endpoint).processSocket(this.socket, @@ -271,7 +271,26 @@ public class AjpNioProcessor extends Abs } - // ------------------------------------------------------ Protected Methods + @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 KeyAttachment attach = (KeyAttachment)socket.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 output(byte[] src, int offset, int length) Modified: tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AjpProcessor.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AjpProcessor.java?rev=1519616&r1=1519615&r2=1519616&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AjpProcessor.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AjpProcessor.java Tue Sep 3 09:38:04 2013 @@ -273,11 +273,13 @@ public class AjpProcessor extends Abstra ((JIoEndpoint)endpoint).processSocketAsync(this.socket, 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 socket.setTimeout(timeout); + } else if (actionCode == ActionCode.ASYNC_DISPATCH) { if (asyncStateMachine.asyncDispatch()) { ((JIoEndpoint)endpoint).processSocketAsync(this.socket, @@ -287,7 +289,12 @@ public class AjpProcessor extends Abstra } - // ------------------------------------------------------ Protected Methods + @Override + protected void resetTimeouts() { + // NO-OP. The AJP BIO connector only uses the timeout value on the + // SocketWrapper for async timeouts. + } + @Override protected void output(byte[] src, int offset, int length) Modified: tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml?rev=1519616&r1=1519615&r2=1519616&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml (original) +++ tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Tue Sep 3 09:38:04 2013 @@ -192,6 +192,10 @@ bodies to be included for responses with status codes and/or request methods that are not permitted to have a response body. (markt) </fix> + <fix> + <bug>55500</bug>: Don't ignore the value of an asynchronous context + timeout when using the AJP NIO connector. (markt) + </fix> </changelog> </subsection> <subsection name="Jasper"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org