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: [email protected]
For additional commands, e-mail: [email protected]