Author: fhanik Date: Wed Mar 24 21:26:47 2010 New Revision: 927182 URL: http://svn.apache.org/viewvc?rev=927182&view=rev Log: Add in a slightly different behavior for dispatch. dispatch() will return immediately, according to spec. But if dispatch is called from the tomcat worker thread, then the dispatch will not happen until the worker thread has backed out of the call. This prevents multiple threads being launched into the same request/response and causing potential concurrency issues. The Async state machine guarantees that multiple dispatch can not be called.
Modified: tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java tomcat/trunk/java/org/apache/catalina/connector/Request.java tomcat/trunk/java/org/apache/catalina/core/StandardWrapperValve.java tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java Modified: tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java?rev=927182&r1=927181&r2=927182&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java (original) +++ tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java Wed Mar 24 21:26:47 2010 @@ -270,26 +270,48 @@ public class CoyoteAdapter implements Ad boolean success = true; try { - // Calling the container - try { - if (status==SocketStatus.TIMEOUT) { - AsyncContextImpl asyncConImpl = (AsyncContextImpl)request.getAsyncContext(); - //TODO SERVLET3 - async - //configure settings for timed out - asyncConImpl.setTimeoutState(); - } - if (status==SocketStatus.ERROR || status==SocketStatus.STOP || status==SocketStatus.DISCONNECT) { - AsyncContextImpl asyncConImpl = (AsyncContextImpl)request.getAsyncContext(); + if (status==SocketStatus.TIMEOUT) { + AsyncContextImpl asyncConImpl = (AsyncContextImpl)request.getAsyncContext(); + //TODO SERVLET3 - async + //configure settings for timed out + asyncConImpl.setTimeoutState(); + } + if (status==SocketStatus.ERROR || status==SocketStatus.STOP || status==SocketStatus.DISCONNECT) { + AsyncContextImpl asyncConImpl = (AsyncContextImpl)request.getAsyncContext(); + //TODO SERVLET3 - async + //configure settings for timed out + asyncConImpl.setErrorState(); + } + while (success) { + AsyncContextImpl impl = (AsyncContextImpl)request.getAsyncContext(); + // Calling the container + if (impl.getState()==AsyncContextImpl.AsyncState.DISPATCHED) { + // Calling the container + try { + impl.complete(); + connector.getContainer().getPipeline().getFirst().invoke(request, response); + } finally { + success = false; + } + } else if (impl.getState()==AsyncContextImpl.AsyncState.STARTED){ //TODO SERVLET3 - async - //configure settings for timed out - asyncConImpl.setErrorState(); + res.action(ActionCode.ACTION_ASYNC_START, request.getAsyncContext()); + async = true; + break; + } else if (impl.getState()==AsyncContextImpl.AsyncState.NOT_STARTED){ + //TODO SERVLET3 - async + async = false; + break; + } else { + try { + connector.getContainer().getPipeline().getFirst().invoke(request, response); + }catch (RuntimeException x) { + success = false; + } finally { + } } - connector.getContainer().getPipeline().getFirst().invoke(request, response); - }catch (RuntimeException x) { - success = false; - } finally { } - + if (request.isComet()) { if (!response.isClosed() && !response.isError()) { if (request.getAvailable() || (request.getContentLength() > 0 && (!request.isParametersParsed()))) { @@ -308,12 +330,7 @@ public class CoyoteAdapter implements Ad request.setFilterChain(null); } } - - if (request.isAsyncStarted()) { - //TODO SERVLET3 - async - res.action(ActionCode.ACTION_ASYNC_START, request.getAsyncContext()); - async = true; - } else if (!comet) { + if (!async && !comet) { response.finishResponse(); req.action(ActionCode.ACTION_POST_REQUEST , null); } @@ -410,11 +427,16 @@ public class CoyoteAdapter implements Ad } } - + AsyncContextImpl asyncConImpl = (AsyncContextImpl)request.getAsyncContext(); if (request.isAsyncStarted()) { - //TODO SERVLET3 - async res.action(ActionCode.ACTION_ASYNC_START, request.getAsyncContext()); async = true; + } else if (asyncConImpl!=null && + (asyncConImpl.getState()==AsyncContextImpl.AsyncState.DISPATCHING || + asyncConImpl.getState()==AsyncContextImpl.AsyncState.COMPLETING || + asyncConImpl.getState()==AsyncContextImpl.AsyncState.TIMING_OUT || + asyncConImpl.getState()==AsyncContextImpl.AsyncState.ERROR_DISPATCHING)) { + asyncDispatch(req, res, SocketStatus.OPEN); } else if (!comet) { response.finishResponse(); req.action(ActionCode.ACTION_POST_REQUEST , null); Modified: tomcat/trunk/java/org/apache/catalina/connector/Request.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/Request.java?rev=927182&r1=927181&r2=927182&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/connector/Request.java (original) +++ tomcat/trunk/java/org/apache/catalina/connector/Request.java Wed Mar 24 21:26:47 2010 @@ -1539,6 +1539,15 @@ public class Request else return asyncContext.isStarted(); } + public boolean isAsyncDispatching() { + if (asyncContext==null) return false; + else return (asyncContext.getState()==AsyncContextImpl.AsyncState.DISPATCHING || + asyncContext.getState()==AsyncContextImpl.AsyncState.TIMING_OUT || + asyncContext.getState()==AsyncContextImpl.AsyncState.STARTED || + asyncContext.getState()==AsyncContextImpl.AsyncState.ERROR_DISPATCHING || + asyncContext.getState()==AsyncContextImpl.AsyncState.COMPLETING); + } + public boolean isAsyncSupported() { // TODO SERVLET3 - async if (this.asyncSupported==null) { Modified: tomcat/trunk/java/org/apache/catalina/core/StandardWrapperValve.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/StandardWrapperValve.java?rev=927182&r1=927181&r2=927182&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/core/StandardWrapperValve.java (original) +++ tomcat/trunk/java/org/apache/catalina/core/StandardWrapperValve.java Wed Mar 24 21:26:47 2010 @@ -217,7 +217,7 @@ final class StandardWrapperValve if (context.getSwallowOutput()) { try { SystemLogHandler.startCapture(); - if (request.isAsyncStarted()) { + if (request.isAsyncDispatching()) { //TODO SERVLET3 - async ((AsyncContextImpl)request.getAsyncContext()).doInternalDispatch(); } else if (comet) { @@ -234,7 +234,7 @@ final class StandardWrapperValve } } } else { - if (request.isAsyncStarted()) { + if (request.isAsyncDispatching()) { //TODO SERVLET3 - async ((AsyncContextImpl)request.getAsyncContext()).doInternalDispatch(); } else if (comet) { Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java?rev=927182&r1=927181&r2=927182&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java Wed Mar 24 21:26:47 2010 @@ -777,6 +777,8 @@ public class Http11NioProcessor extends if ( rp.getStage() != org.apache.coyote.Constants.STAGE_SERVICE ) { //async handling dispatch.set(true); endpoint.processSocket(this.socket, SocketStatus.STOP, true); + } else { + dispatch.set(true); } } else if (actionCode == ActionCode.ACTION_ASYNC_SETTIMEOUT) { //TODO SERVLET3 - async @@ -793,7 +795,7 @@ public class Http11NioProcessor extends endpoint.processSocket(this.socket, SocketStatus.OPEN, true); dispatch.set(true); } else { - + dispatch.set(true); } } } Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java?rev=927182&r1=927181&r2=927182&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java Wed Mar 24 21:26:47 2010 @@ -621,7 +621,7 @@ public class Http11Processor extends Abs dispatch.set(true); endpoint.processSocket(this.socket, SocketStatus.STOP); } else { - //TODO SERVLET3 async=false + dispatch.set(true); } } else if (actionCode == ActionCode.ACTION_ASYNC_SETTIMEOUT) { //TODO SERVLET3 - async @@ -636,7 +636,7 @@ public class Http11Processor extends Abs endpoint.processSocket(this.socket, SocketStatus.OPEN); dispatch.set(true); } else { - //TODO SERVLET3 - do nothing? + dispatch.set(true); } } --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org