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 2018/06/19 11:58:55 UTC
svn commit: r1833825 - in /tomcat/trunk: java/org/apache/coyote/
java/org/apache/coyote/http11/upgrade/ webapps/docs/
Author: markt
Date: Tue Jun 19 11:58:55 2018
New Revision: 1833825
URL: http://svn.apache.org/viewvc?rev=1833825&view=rev
Log:
Avoid unnecessary processing of async timeouts.
Modified:
tomcat/trunk/java/org/apache/coyote/AbstractProcessor.java
tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java
tomcat/trunk/java/org/apache/coyote/AsyncStateMachine.java
tomcat/trunk/java/org/apache/coyote/Processor.java
tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeProcessorBase.java
tomcat/trunk/webapps/docs/changelog.xml
Modified: tomcat/trunk/java/org/apache/coyote/AbstractProcessor.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/AbstractProcessor.java?rev=1833825&r1=1833824&r2=1833825&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/AbstractProcessor.java (original)
+++ tomcat/trunk/java/org/apache/coyote/AbstractProcessor.java Tue Jun 19 11:58:55 2018
@@ -51,6 +51,7 @@ public abstract class AbstractProcessor
protected final Adapter adapter;
protected final AsyncStateMachine asyncStateMachine;
private volatile long asyncTimeout = -1;
+ private volatile long asyncTimeoutGeneration = 0;
protected final Request request;
protected final Response response;
protected volatile SocketWrapperBase<?> socketWrapper = null;
@@ -620,10 +621,17 @@ public abstract class AbstractProcessor
private void doTimeoutAsync() {
// Avoid multiple timeouts
setAsyncTimeout(-1);
+ asyncTimeoutGeneration = asyncStateMachine.getCurrentGeneration();
processSocketEvent(SocketEvent.TIMEOUT, true);
}
+ @Override
+ public boolean checkAsyncTimeoutGeneration() {
+ return asyncTimeoutGeneration == asyncStateMachine.getCurrentGeneration();
+ }
+
+
public void setAsyncTimeout(long timeout) {
asyncTimeout = timeout;
}
Modified: tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java?rev=1833825&r1=1833824&r2=1833825&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java (original)
+++ tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java Tue Jun 19 11:58:55 2018
@@ -683,6 +683,16 @@ public abstract class AbstractProtocol<S
processor, socket));
}
+ // Async timeouts are calculated on a dedicated thread and then
+ // dispatched. Because of delays in the dispatch process, the
+ // timeout may no longer be required. Check here and avoid
+ // unnecessary processing.
+ if (SocketEvent.TIMEOUT == status && (processor == null ||
+ !processor.isAsync() || !processor.checkAsyncTimeoutGeneration())) {
+ // This is effectively a NO-OP
+ return SocketState.OPEN;
+ }
+
if (processor != null) {
// Make sure an async timeout doesn't fire
getProtocol().removeWaitingProcessor(processor);
Modified: tomcat/trunk/java/org/apache/coyote/AsyncStateMachine.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/AsyncStateMachine.java?rev=1833825&r1=1833824&r2=1833825&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/AsyncStateMachine.java [UTF-8] (original)
+++ tomcat/trunk/java/org/apache/coyote/AsyncStateMachine.java [UTF-8] Tue Jun 19 11:58:55 2018
@@ -18,6 +18,7 @@ package org.apache.coyote;
import java.security.AccessController;
import java.security.PrivilegedAction;
+import java.util.concurrent.atomic.AtomicLong;
import org.apache.tomcat.util.net.AbstractEndpoint.Handler.SocketState;
import org.apache.tomcat.util.res.StringManager;
@@ -189,6 +190,7 @@ class AsyncStateMachine {
private volatile AsyncState state = AsyncState.DISPATCHED;
private volatile long lastAsyncStart = 0;
+ private AtomicLong generation = new AtomicLong(0);
// Need this to fire listener on complete
private AsyncContextCallback asyncCtxt = null;
private final AbstractProcessor processor;
@@ -234,8 +236,13 @@ class AsyncStateMachine {
return lastAsyncStart;
}
+ long getCurrentGeneration() {
+ return generation.get();
+ }
+
synchronized void asyncStart(AsyncContextCallback asyncCtxt) {
if (state == AsyncState.DISPATCHED) {
+ generation.incrementAndGet();
state = AsyncState.STARTING;
this.asyncCtxt = asyncCtxt;
lastAsyncStart = System.currentTimeMillis();
Modified: tomcat/trunk/java/org/apache/coyote/Processor.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/Processor.java?rev=1833825&r1=1833824&r2=1833825&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/Processor.java (original)
+++ tomcat/trunk/java/org/apache/coyote/Processor.java Tue Jun 19 11:58:55 2018
@@ -110,4 +110,15 @@ public interface Processor {
* an existing multiplexed connection.
*/
void pause();
+
+ /**
+ * Check to see if the async generation (each cycle of async increments the
+ * generation of the AsyncStateMachine) is the same as the generation when
+ * the most recent async timeout was triggered. This is intended to be used
+ * to avoid unnecessary processing.
+ *
+ * @return {@code true} If the async generation has not changed since the
+ * async timeout was triggered
+ */
+ boolean checkAsyncTimeoutGeneration();
}
Modified: tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeProcessorBase.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeProcessorBase.java?rev=1833825&r1=1833824&r2=1833825&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeProcessorBase.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeProcessorBase.java Tue Jun 19 11:58:55 2018
@@ -94,4 +94,10 @@ public abstract class UpgradeProcessorBa
public void timeoutAsync(long now) {
// NO-OP
}
+
+
+ @Override
+ public boolean checkAsyncTimeoutGeneration() {
+ return false;
+ }
}
Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1833825&r1=1833824&r2=1833825&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Tue Jun 19 11:58:55 2018
@@ -211,6 +211,9 @@
Fix <code>NullPointerException</code> thrown from <code>
replaceSystemProperties()</code> when trying to log messages. (csutherl)
</fix>
+ <fix>
+ Avoid unnecessary processing of async timeouts. (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Jasper">
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org