Hi Mark,

On Mon, Jun 12, 2017 at 8:42 PM, <ma...@apache.org> wrote:

> Author: markt
> Date: Mon Jun 12 18:42:32 2017
> New Revision: 1798509
>
> URL: http://svn.apache.org/viewvc?rev=1798509&view=rev
> Log:
> Make asynchronous error handling more robust. In particular ensure that
> onError() is called for any registered AsyncListeners after an I/O error on
> a non-container thread.
>
> Modified:
>     tomcat/trunk/conf/logging.properties
>     tomcat/trunk/java/org/apache/coyote/AbstractProcessor.java
>     tomcat/trunk/java/org/apache/coyote/AsyncStateMachine.java
>     tomcat/trunk/webapps/docs/changelog.xml
>
> Modified: tomcat/trunk/conf/logging.properties
> URL: http://svn.apache.org/viewvc/tomcat/trunk/conf/logging.prope
> rties?rev=1798509&r1=1798508&r2=1798509&view=diff
> ============================================================
> ==================
> --- tomcat/trunk/conf/logging.properties (original)
> +++ tomcat/trunk/conf/logging.properties Mon Jun 12 18:42:32 2017
> @@ -65,6 +65,8 @@ org.apache.catalina.core.ContainerBase.[
>
>  # To see debug messages for HTTP/2 handling, uncomment the following line:
>  #org.apache.coyote.http2.level = FINE
> +org.apache.coyote.level = FINEST
> +org.apache.catalina.level = FINEST
>

Look like debug leftovers.


>
>  # To see debug messages for WebSocket handling, uncomment the following
> line:
>  #org.apache.tomcat.websocket.level = FINE
>
> Modified: tomcat/trunk/java/org/apache/coyote/AbstractProcessor.java
> URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/co
> yote/AbstractProcessor.java?rev=1798509&r1=1798508&r2=1798509&view=diff
> ============================================================
> ==================
> --- tomcat/trunk/java/org/apache/coyote/AbstractProcessor.java (original)
> +++ tomcat/trunk/java/org/apache/coyote/AbstractProcessor.java Mon Jun 12
> 18:42:32 2017
> @@ -95,6 +95,7 @@ public abstract class AbstractProcessor
>              // 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();
>              
> getLog().info(sm.getString("abstractProcessor.nonContainerThreadError"),
> t);
>              processSocketEvent(SocketEvent.ERROR, true);
>          }
>
> Modified: tomcat/trunk/java/org/apache/coyote/AsyncStateMachine.java
> URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/co
> yote/AsyncStateMachine.java?rev=1798509&r1=1798508&r2=1798509&view=diff
> ============================================================
> ==================
> --- tomcat/trunk/java/org/apache/coyote/AsyncStateMachine.java [UTF-8]
> (original)
> +++ tomcat/trunk/java/org/apache/coyote/AsyncStateMachine.java [UTF-8]
> Mon Jun 12 18:42:32 2017
> @@ -66,38 +66,49 @@ import org.apache.tomcat.util.security.P
>   *                    differences required to avoid race conditions
> during error
>   *                    handling.
>   * DISPATCHING      - The dispatch is being processed.
> + * MUST_ERROR       - ServletRequest.startAsync() has been called
> followed by an
> + *                    I/O error on a non-container thread. The main
> purpose of
> + *                    this state is to prevent additional async actions
> + *                    (complete(), dispatch() etc.) on the non-container
> thread.
> + *                    The container will perform the necessary error
> handling,
> + *                    including ensuring that the AsyncLister.onError()
> method
> + *                    is called.
>   * ERROR            - Something went wrong.
>   *
> - * |-----------------»------|
> - * |                       \|/ /---«-------------------------
> ------«------------------------------|
> - * |   |----------«-----E R R O R--«-----------------------«--
> -----------------------------|      |
> - * |   |      complete() /|\/|\\ \-«--------------------------------«-------|
>             |      |
> - * |   |                  |  |  \
>    |              |      |
> - * |   |    |-----»-------|  |   \-----------»----------|
>    |              |      |
> - * |   |    |                |                          |dispatch()
>    |              |      |
> - * |   |    |                |                         \|/
>   ^              |      |
> - * |   |    |                |          |--|timeout()   |
>    |              |      |
> - * |   |    |     post()     |          | \|/           |     post()
>   |              |      |
> - * |   |    |    |---------- | --»DISPATCHED«---------- |
> --------------COMPLETING«-----|  |      |
> - * |   |    |    |           |   /|\/|\ |               |
> | /|\ /|\      |  |      |
> - * |   |    |    |    |---»- | ---|  |  |startAsync()   |
>  timeout()|--|   |       |  |      |
> - * |   |    ^    ^    |      |       |  |               |
>        |       |  ^      |
> - * |   |    |    |    |   |-- \ -----|  |   complete()  |
>        |post() |  |      |
> - * |   |    |    |    |   |    \        |     /--»----- |
> ---COMPLETE_PENDING-»-|       ^  |      |
> - * |   |    |    |    |   |     \       |    /          |
>                |  |      |
> - * |   |    |    |    |   ^      \      |   /           |
>                |  |      |
> - * |  \|/   |    |    |   |       \    \|/ /   post()   |
>     complete() |  |      |
> - * | MUST_COMPLETE-«- | - | --«----STARTING--»--------- | ------------|
>      /---»-----|  |      |
> - * |  /|\    /|\      |   |  complete()  | \            |             |
>     /             |      ^
> - * |   |      |       |   |              |  \           |    post()   |
>    /   error()    |      |
> - * |   |      |       ^   |    dispatch()|   \          |    |-----|  |
>   //------»-------|      |
> - * |   |      |       |   |              |    \         |    |     |  |
>  //                      |
> - * |   |      |       |   |             \|/    \        |    |    \|/\|/
> //       post()          |
> + *                           |-----«----------------------
> ---------«------------------------------|
> + *                           |
>                         |
> + *                           |      error()
>                          |
> + * |-----------------»---|   |  |--«--------MUST_ERROR--------
> -------«------------------------|   |
> + * |                    \|/ \|/\|/
>                     |   |
> + * |   |----------«-----E R R O R--«-----------------------«--
> -----------------------------|  |   |
> + * |   |      complete() /|\/|\\ \-«--------------------------------«-------|
>             |  |   |
> + * |   |                  |  |  \
>    |              |  |   |
> + * |   |    |-----»-------|  |   \-----------»----------|
>    |              |  |   |
> + * |   |    |                |                          |dispatch()
>    |              |  ^   |
> + * |   |    |                |                         \|/
>   ^              |  |   |
> + * |   |    |                |          |--|timeout()   |
>    |              |  |   |
> + * |   |    |     post()     |          | \|/           |     post()
>   |              |  |   |
> + * |   |    |    |---------- | --»DISPATCHED«---------- |
> --------------COMPLETING«-----|  |  |   |
> + * |   |    |    |           |   /|\/|\ |               |
> | /|\ /|\      |  |  |   |
> + * |   |    |    |    |---»- | ---|  |  |startAsync()   |
>  timeout()|--|   |       |  |  |   |
> + * |   |    ^    ^    |      |       |  |               |
>        |       |  ^  |   |
> + * |   |    |    |    |   |-- \ -----|  |   complete()  |
>        |post() |  |  |   |
> + * |   |    |    |    |   |    \        |     /--»----- |
> ---COMPLETE_PENDING-»-|       ^  |  |   |
> + * |   |    |    |    |   |     \       |    /          |
>                |  |  |   |
> + * |   |    |    |    |   ^      \      |   /           |
>     complete() |  |  |   |
> + * |  \|/   |    |    |   |       \    \|/ /   post()   |
>      /---»-----|  |  ^   |
> + * | MUST_COMPLETE-«- | - | --«----STARTING--»--------- | ------------|
>     /             |  |   |
> + * |  /|\    /|\      |   |  complete()  | \            |             |
>    /   error()    |  |   ^
> + * |   |      |       |   |              |  \           |             |
>   //---»----------|  |   |
> + * |   |      |       ^   |    dispatch()|   \          |    post()   |
>  //                  |   |
> + * |   |      |       |   |              |    \         |    |-----|  |
> //   nct-io-error    |   |
> + * |   |      |       |   |              |     \        |    |     |  |
> ///---»---------------|   |
> + * |   |      |       |   |             \|/     \       |    |    \|/\|
> |||                       |
>   * |   |      |       |   |--«--MUST_DISPATCH-----«-----|
> |--«--STARTED«---------«---------|   |
> - * |   |      |       | dispatched() /|\   |     \                / |
>  |                     |   |
> - * |   |      |       |               |    |      \              /  |
>  |                     |   |
> - * |   |      |       |               |    |       \            /   |
>  |                     |   |
> - * |   |      |       |               |    |post()  \           |   |
>  |                     ^   |
> + * |   |      |       | dispatched() /|\   |      \               / |
>  |        post()       |   |
> + * |   |      |       |               |    |       \             /  |
>  |                     |   |
> + * |   |      |       |               |    |        \           /   |
>  |                     |   |
> + * |   |      |       |               |    |post()  |           |   |
>  |                     ^   |
>   * ^   |      ^       |               |    |       \|/          |   |
>  |asyncOperation()     |   |
>   * |   |      |       ^               |    |  DISPATCH_PENDING  |   |
>  |                     |   |
>   * |   |      |       |               |    |  |post()           |   |
>  |                     |   |
> @@ -142,6 +153,7 @@ public class AsyncStateMachine {
>          DISPATCH_PENDING(true,  true,  false, false),
>          DISPATCHING     (true,  false, false, true),
>          READ_WRITE_OP   (true,  true,  false, false),
> +        MUST_ERROR      (true,  true,  false, false),
>          ERROR           (true,  true,  false, false);
>
>          private final boolean isAsync;
> @@ -384,6 +396,18 @@ public class AsyncStateMachine {
>      }
>
>
> +    public synchronized void asyncMustError() {
> +        if (state == AsyncState.STARTED) {
> +            clearNonBlockingListeners();
> +            state = AsyncState.MUST_ERROR;
> +        } else {
> +            throw new IllegalStateException(
> +                    sm.getString("asyncStateMachine.invalidAsyncState",
> +                            "asyncMustError()", state));
> +        }
> +    }
> +
> +
>      public synchronized void asyncError() {
>          if (state == AsyncState.STARTING ||
>                  state == AsyncState.STARTED ||
> @@ -391,7 +415,8 @@ public class AsyncStateMachine {
>                  state == AsyncState.TIMING_OUT ||
>                  state == AsyncState.MUST_COMPLETE ||
>                  state == AsyncState.READ_WRITE_OP ||
> -                state == AsyncState.COMPLETING) {
> +                state == AsyncState.COMPLETING ||
> +                state == AsyncState.MUST_ERROR) {
>              clearNonBlockingListeners();
>              state = AsyncState.ERROR;
>          } else {
>
> Modified: tomcat/trunk/webapps/docs/changelog.xml
> URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/chang
> elog.xml?rev=1798509&r1=1798508&r2=1798509&view=diff
> ============================================================
> ==================
> --- tomcat/trunk/webapps/docs/changelog.xml (original)
> +++ tomcat/trunk/webapps/docs/changelog.xml Mon Jun 12 18:42:32 2017
> @@ -117,6 +117,12 @@
>          changed the status code recorded in the access log when the client
>          dropped the connection from 200 to 500. (markt)
>        </fix>
> +      <fix>
> +        Make asynchronous error handling more robust. In particular
> ensure that
> +        <code>onError()</code> is called for any registered
> +        <code>AsyncListener</code>s after an I/O error on a non-container
> +        thread. (markt)
> +      </fix>
>      </changelog>
>    </subsection>
>    <subsection name="Jasper">
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: dev-h...@tomcat.apache.org
>
>

Reply via email to