Author: markt
Date: Mon Aug 17 07:28:18 2015
New Revision: 1696199

URL: http://svn.apache.org/r1696199
Log:
Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=58157
Ensure that the handling of async timeouts does not result in an unnecessary 
dispatch to a container thread that could result in the current socket being
added to the Poller multiple times and multiple attempts to process the same 
event for the same socket.

Modified:
    tomcat/trunk/java/org/apache/coyote/AsyncStateMachine.java

Modified: tomcat/trunk/java/org/apache/coyote/AsyncStateMachine.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/AsyncStateMachine.java?rev=1696199&r1=1696198&r2=1696199&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/AsyncStateMachine.java [UTF-8] 
(original)
+++ tomcat/trunk/java/org/apache/coyote/AsyncStateMachine.java [UTF-8] Mon Aug 
17 07:28:18 2015
@@ -73,20 +73,20 @@ import org.apache.tomcat.util.security.P
  * |   |      |       |               |                 |             |     
/-----------|         |
  * |   |      |       ^               |dispatch()       |             |    /   
                   |
  * |   |      |       |               |                 |             |   /    
                   |
- * |   |      |       |              \|/                /            \|/ /    
postProcess()       |
- * |   |      |       |         MUST_DISPATCH          /           
STARTED«---------«---------|   |
- * |   |      |       |           |                   /           / |   |      
               |   |
- * |   |      |       |           |postProcess()     /           /  |   |      
               ^   |
- * ^   |      ^       |           |                 /           /   |   
|asyncOperation()     |   |
- * |   |      |       |           |                /           /    |   |      
               |   |
- * |   |      |       |           |   |---------- / ----------/     |   
|--READ_WRITE_OP--»---|   |
- * |   |      |       |           |   |          /   dispatch()     |          
  |  |  |          |
- * |   |      |       |           |   |   |-----/               auto|          
  |  |  |   error()|
- * |   |      |       | auto     \|/ \|/ \|/                        |  
dispatch()|  |  |-»--------|
- * |   |      |       |---«------DISPATCHING«--------«------------- | 
------«----|  |
- * |   |      |                      /|\                            |          
     |
+ * |   |      |       |              \|/                |            \|/ /    
postProcess()       |
+ * |   |      |       |----«----MUST_DISPATCH-----«-----|          
STARTED«---------«---------|   |
+ * |   |      |       |  auto        /|\                          / |   |      
               |   |
+ * |   |      |       |               |                          /  |   |      
               ^   |
+ * ^   |      ^       |               |                         /   |   
|asyncOperation()     |   |
+ * |   |      |       ^               |                        /    |   |      
               |   |
+ * |   |      |       |               |         |-------------/     |   
|--READ_WRITE_OP--»---|   |
+ * |   |      |       |               |         |    dispatch()     |          
  |  |  |          |
+ * |   |      |       |               |         |               auto|          
  |  |  |   error()|
+ * |   |      |       | auto          |        \|/                  |  
dispatch()|  |  |-»--------|
+ * |   |      |       |---«---------- | ---DISPATCHING«-----«------ | 
------«----|  |
+ * |   |      |                       |                             |          
     |
  * |   |      |                       |       dispatch()           \|/         
     |
- * |   |      |                       |-----------------------TIMING_OUT       
     |
+ * |   |      |                       |-----------«-----------TIMING_OUT       
     |
  * |   |      |                                                 |   |          
     |
  * |   |      |-------«----------------------------------«------|   |          
     |
  * |   |                          complete()                        |          
     |
@@ -296,7 +296,11 @@ public class AsyncStateMachine {
     public synchronized boolean asyncDispatch() {
         pauseNonContainerThread();
         boolean doDispatch = false;
-        if (state == AsyncState.STARTING) {
+        if (state == AsyncState.STARTING ||
+                state == AsyncState.TIMING_OUT ||
+                state == AsyncState.ERROR) {
+            // In these three cases processing is on a container thread so no
+            // need to transfer processing to a new container thread
             state = AsyncState.MUST_DISPATCH;
         } else if (state == AsyncState.STARTED) {
             state = AsyncState.DISPATCHING;
@@ -307,9 +311,7 @@ public class AsyncStateMachine {
             // request/response associated with the AsyncContext so need a new
             // container thread to process the different request/response.
             doDispatch = true;
-        } else if (state == AsyncState.READ_WRITE_OP ||
-                state == AsyncState.TIMING_OUT ||
-                state == AsyncState.ERROR) {
+        } else if (state == AsyncState.READ_WRITE_OP) {
             state = AsyncState.DISPATCHING;
             // If on a container thread then the socket will be added to the
             // poller poller when the thread exits the
@@ -328,7 +330,8 @@ public class AsyncStateMachine {
 
 
     public synchronized void asyncDispatched() {
-        if (state == AsyncState.DISPATCHING) {
+        if (state == AsyncState.DISPATCHING ||
+                state == AsyncState.MUST_DISPATCH) {
             state = AsyncState.DISPATCHED;
         } else {
             throw new IllegalStateException(



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

Reply via email to