You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2019/10/17 21:32:52 UTC

[tomcat] branch master updated: Update state definitions and associated diagram (now a lot simpler)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new b641633  Update state definitions and associated diagram (now a lot simpler)
b641633 is described below

commit b6416332dfc490d600b26f0bd818c308fa7eb8a2
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Thu Oct 17 22:32:17 2019 +0100

    Update state definitions and associated diagram (now a lot simpler)
---
 java/org/apache/coyote/AsyncStateMachine.java | 167 ++++++++++++--------------
 1 file changed, 75 insertions(+), 92 deletions(-)

diff --git a/java/org/apache/coyote/AsyncStateMachine.java b/java/org/apache/coyote/AsyncStateMachine.java
index 71683a2..be4b953 100644
--- a/java/org/apache/coyote/AsyncStateMachine.java
+++ b/java/org/apache/coyote/AsyncStateMachine.java
@@ -31,108 +31,91 @@ import org.apache.tomcat.util.security.PrivilegedSetTccl;
  * <pre>
  * The internal states that are used are:
  * DISPATCHED       - Standard request. Not in Async mode.
- * STARTING         - ServletRequest.startAsync() has been called but the
- *                    request in which that call was made has not finished
- *                    processing.
- * STARTED          - ServletRequest.startAsync() has been called and the
- *                    request in which that call was made has finished
- *                    processing.
+ * STARTING         - ServletRequest.startAsync() has been called from
+ *                    Servlet.service() but service() has not exited.
+ * STARTED          - ServletRequest.startAsync() has been called from
+ *                    Servlet.service() and service() has exited.
  * READ_WRITE_OP    - Performing an asynchronous read or write.
  * MUST_COMPLETE    - ServletRequest.startAsync() followed by complete() have
  *                    been called during a single Servlet.service() method. The
- *                    complete() will be processed as soon as the request
- *                    finishes.
- * COMPLETE_PENDING - ServletRequest.startAsync() has been called and before the
- *                    request in which that call was had finished processing,
- *                    complete() was called for a non-container thread. The
- *                    complete() will be processed as soon as the request
- *                    finishes. This is different to MUST_COMPLETE because of
- *                    differences required to avoid race conditions during error
- *                    handling.
+ *                    complete() will be processed as soon as Servlet.service()
+ *                    exits.
+ * COMPLETE_PENDING - ServletRequest.startAsync() has been called from
+ *                    Servlet.service() but, before service() exited, complete()
+ *                    was called from another thread. The complete() will
+ *                    be processed as soon as Servlet.service() exits.
  * COMPLETING       - The call to complete() was made once the request was in
- *                    the STARTED state. May or may not be triggered by a
- *                    container thread - depends if start(Runnable) was used.
+ *                    the STARTED state.
  * TIMING_OUT       - The async request has timed out and is waiting for a call
- *                    to complete(). If that isn't made, the error state will
- *                    entered.
+ *                    to complete() or dispatch(). If that isn't made, the error
+ *                    state will be entered.
  * MUST_DISPATCH    - ServletRequest.startAsync() followed by dispatch() have
  *                    been called during a single Servlet.service() method. The
- *                    dispatch() will be processed as soon as the request
- *                    finishes.
- * DISPATCH_PENDING - ServletRequest.startAsync() has been called and before the
- *                    request in which that call was had finished processing,
- *                    dispatch() was called for a non-container thread. The
- *                    dispatch() will be processed as soon as the request
- *                    finishes. This is different to MUST_DISPATCH because of
- *                    differences required to avoid race conditions during error
- *                    handling.
+ *                    dispatch() will be processed as soon as Servlet.service()
+ *                    exits.
+ * DISPATCH_PENDING - ServletRequest.startAsync() has been called from
+ *                    Servlet.service() but, before service() exited, dispatch()
+ *                    was called from another thread. The dispatch() will
+ *                    be processed as soon as Servlet.service() exits.
  * 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.
+ * MUST_ERROR       - ServletRequest.startAsync() has been called from
+ *                    Servlet.service() but, before service() exited, an I/O
+ *                    error occured on another thread. The container will
+ *                    perform the necessary error handling when
+ *                    Servlet.service() exits.
  * ERROR            - Something went wrong.
  *
- *                           |-----«-------------------------------«------------------------------|
- *                           |                                                                    |
- *                           |      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()       |   |
- * |   |      |       |               |    |       \             /  |   |                     |   |
- * |   |      |       |               |    |        \           /   |   |                     |   |
- * |   |      |       |               |    |post()  |           |   |   |                     ^   |
- * ^   |      ^       |               |    |       \|/          |   |   |asyncOperation()     |   |
- * |   |      |       ^               |    |  DISPATCH_PENDING  |   |   |                     |   |
- * |   |      |       |               |    |  |post()           |   |   |                     |   |
- * |   |      |       |               |    |  |      |----------|   |   |»-READ_WRITE_OP--»---|   |
- * |   |      |       |               |    |  |      |  dispatch()  |            |  |  |          |
- * |   |      |       |               |    |  |      |              |            |  |  |          |
- * |   |      |       |post()         |    |  |      |     timeout()|            |  |  |   error()|
- * |   |      |       |dispatched()   |   \|/\|/    \|/             |  dispatch()|  |  |-»--------|
- * |   |      |       |---«---------- | ---DISPATCHING«-----«------ | ------«----|  |
- * |   |      |                       |     |   /|\                 |               |
- * |   |      |                       |     |----|                  |               |
- * |   |      |                       |    timeout()                |               |
- * |   |      |                       |                             |               |
- * |   |      |                       |       dispatch()           \|/              |
- * |   |      |                       |-----------«-----------TIMING_OUT            |
- * |   |      |                                                 |   |               |
- * |   |      |-------«----------------------------------«------|   |               |
- * |   |                          complete()                        |               |
- * |   |                                                            |               |
- * |«- | ----«-------------------«-------------------------------«--|               |
- *     |                           error()                                          |
- *     |                                                  complete()                |
- *     |----------------------------------------------------------------------------|
+ *
+ * The valid state transitions are:
+ *
+ *                  post()                                        dispatched()
+ *    |-------»------------------»---------|    |-------«-----------------------«-----|
+ *    |                                    |    |                                     |
+ *    |                                    |    |        post()                       |
+ *    |               post()              \|/  \|/       dispatched()                 |
+ *    |           |-----»----------------»DISPATCHED«-------------«-------------|     |
+ *    |           |                          | /|\ |                            |     |
+ *    |           |              startAsync()|  |--|timeout()                   |     |
+ *    ^           |                          |                                  |     |
+ *    |           |        complete()        |                  dispatch()      ^     |
+ *    |           |   |--«---------------«-- | ---«--MUST_ERROR--»-----|        |     |
+ *    |           |   |                      |         /|\             |        |     |
+ *    |           ^   |                      |          |              |        |     |
+ *    |           |   |                      |    /-----|error()       |        |     |
+ *    |           |   |                      |   /                     |        ^     |
+ *    |           |  \|/  ST-complete()     \|/ /   ST-dispatch()     \|/       |     |
+ *    |    MUST_COMPLETE«--------«--------STARTING--------»---------»MUST_DISPATCH    |
+ *    |                                    / | \                                      |
+ *    |                                   /  |  \                                     |
+ *    |                    OT-complete() /   |   \    OT-dispatch()                   |
+ *    |   COMPLETE_PENDING«------«------/    |    \-------»---------»DISPATCH_PENDING |
+ *    |          |                           |                           |            |
+ *    |    post()|   timeout()         post()|   post()            post()|  timeout() |
+ *    |          |   |--|                    |  |--|                     |    |--|    |
+ *    |         \|/ \|/ |   complete()      \|/\|/ |   dispatch()       \|/  \|/ |    |
+ *    |--«-----COMPLETING«--------«----------STARTED--------»---------»DISPATCHING----|
+ *            /|\  /|\ /|\                   | /|\ \                   /|\ /|\ /|\
+ *             |    |   |                    |  \   \asyncOperation()   |   |   |
+ *             |    |   |           timeout()|   \   \                  |   |   |
+ *             |    |   |                    |    \   \                 |   |   |
+ *             |    |   |                    |     \   \                |   |   |
+ *             |    |   |                    |      \   \               |   |   |
+ *             |    |   |                    |       \   \              |   |   |
+ *             |    |   |                    |  post()\   \   dispatch()|   |   |
+ *             |    |   |   complete()       |         \ \|/            |   |   |
+ *             |    |   |---«------------«-- | --«---READ_WRITE----»----|   |   |
+ *             |    |                        |                              |   |
+ *             |    |       complete()      \|/         dispatch()          |   |
+ *             |    |------------«-------TIMING_OUT--------»----------------|   |
+ *             |                                                                |
+ *             |            complete()                     dispatch()           |
+ *             |---------------«-----------ERROR--------------»-----------------|
+ *
+ *
+ * Notes: * For clarity, the transitions to ERROR which are valid from every state apart from
+ *          STARTING are not shown.
+ *        * All transitions may happen on either the Servlet.service() thread (ST) or on any
+ *          other thread (OT) unless explicitly marked.
  * </pre>
  */
 class AsyncStateMachine {


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