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