This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 7.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit 09044a981e182f28ca1c86a2f8cbf63f7e6e17e1
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Mon Oct 14 16:18:17 2019 +0100

    Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=63816 async errors
    
    Handle I/O errors on a non-container thread after asynchronous
    processing has been started but before the container thread that started
    asynchronous processing has completed processing the current
    request/response.
---
 java/org/apache/coyote/AbstractProcessor.java | 13 +++---------
 java/org/apache/coyote/AsyncStateMachine.java | 30 +++------------------------
 webapps/docs/changelog.xml                    |  6 ++++++
 3 files changed, 12 insertions(+), 37 deletions(-)

diff --git a/java/org/apache/coyote/AbstractProcessor.java 
b/java/org/apache/coyote/AbstractProcessor.java
index e74c385..fdd90a6 100644
--- a/java/org/apache/coyote/AbstractProcessor.java
+++ b/java/org/apache/coyote/AbstractProcessor.java
@@ -97,17 +97,10 @@ public abstract class AbstractProcessor<S> implements 
ActionHook, Processor<S> {
         if (t != null) {
             request.setAttribute(RequestDispatcher.ERROR_EXCEPTION, t);
         }
-        if (blockIo && !ContainerThreadMarker.isContainerThread() && 
isAsync()) {
-            // The error occurred on a non-container thread during async
-            // processing which means not all of the necessary clean-up will
-            // have been completed. Dispatch to a container thread to do the
-            // clean-up. Need to do it this way to ensure that all the 
necessary
-            // clean-up is performed.
-            asyncStateMachine.asyncMustError();
-            if (getLog().isDebugEnabled()) {
-                
getLog().debug(sm.getString("abstractProcessor.nonContainerThreadError"), t);
+        if (blockIo && isAsync()) {
+            if (asyncStateMachine.asyncError()) {
+                getEndpoint().processSocketAsync(socketWrapper, 
SocketStatus.ERROR);
             }
-            getEndpoint().processSocketAsync(socketWrapper, 
SocketStatus.ERROR);
         }
     }
 
diff --git a/java/org/apache/coyote/AsyncStateMachine.java 
b/java/org/apache/coyote/AsyncStateMachine.java
index 07f9b5c..178c1ad 100644
--- a/java/org/apache/coyote/AsyncStateMachine.java
+++ b/java/org/apache/coyote/AsyncStateMachine.java
@@ -145,7 +145,6 @@ public class AsyncStateMachine<S> {
         MUST_DISPATCH   (true,  true,  false, true),
         DISPATCH_PENDING(true,  true,  false, false),
         DISPATCHING     (true,  false, false, true),
-        MUST_ERROR      (true,  true,  false, false),
         ERROR           (true,  true,  false, false);
 
         private final boolean isAsync;
@@ -378,35 +377,12 @@ public class AsyncStateMachine<S> {
     }
 
 
-    public synchronized void asyncMustError() {
-        if (state == AsyncState.STARTED) {
-            state = AsyncState.MUST_ERROR;
-        } else {
-            throw new IllegalStateException(
-                    sm.getString("asyncStateMachine.invalidAsyncState",
-                            "asyncMustError()", state));
-        }
-    }
-
-
     public synchronized boolean asyncError() {
-        boolean doDispatch = false;
-        if (state == AsyncState.STARTING ||
-                state == AsyncState.STARTED ||
-                state == AsyncState.DISPATCHED ||
-                state == AsyncState.TIMING_OUT ||
-                state == AsyncState.MUST_COMPLETE ||
-                state == AsyncState.COMPLETING ||
-                state == AsyncState.MUST_ERROR) {
-            state = AsyncState.ERROR;
-        } else {
-            throw new IllegalStateException(
-                    sm.getString("asyncStateMachine.invalidAsyncState",
-                            "asyncError()", state));
-        }
-        return doDispatch;
+        state = AsyncState.ERROR;
+        return !ContainerThreadMarker.isContainerThread();
     }
 
+
     public synchronized void asyncRun(Runnable runnable) {
         if (state == AsyncState.STARTING || state ==  AsyncState.STARTED) {
             // Execute the runnable using a container thread from the
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index b042f39..924b71a 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -81,6 +81,12 @@
         <code>AsyncListener.onTimeout()</code> or
         <code>AsyncListener.onError()</code>. (markt)
       </fix>
+      <fix>
+        <bug>63816</bug>: Correctly handle I/O errors on a non-container thread
+        after asynchronous processing has been started but before the container
+        thread that started asynchronous processing has completed processing 
the
+        current request/response. (markt)
+      </fix>
     </changelog>
   </subsection>
 </section>


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

Reply via email to