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

Reply via email to