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

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


The following commit(s) were added to refs/heads/10.0.x by this push:
     new 4957254  Fix build. Use new sendResetLock in async handler
4957254 is described below

commit 4957254359e6448aef70a602dd49bac878efdeb5
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Mon Jan 3 19:05:01 2022 +0000

    Fix build. Use new sendResetLock in async handler
---
 .../coyote/http2/Http2AsyncUpgradeHandler.java     | 24 ++++++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java 
b/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java
index 15ec1d1..d79a4b7 100644
--- a/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java
+++ b/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java
@@ -45,6 +45,8 @@ public class Http2AsyncUpgradeHandler extends 
Http2UpgradeHandler {
     // Because of the compression used, headers need to be written to the
     // network in the same order they are generated.
     private final Object headerWriteLock = new Object();
+    // Ensures thread triggers the stream reset is the first to send a RST 
frame
+    private final Object sendResetLock = new Object();
     private final AtomicReference<Throwable> error = new AtomicReference<>();
     private final AtomicReference<IOException> applicationIOE = new 
AtomicReference<>();
 
@@ -123,7 +125,7 @@ public class Http2AsyncUpgradeHandler extends 
Http2UpgradeHandler {
 
 
     @Override
-    void sendStreamReset(StreamException se) throws IOException {
+    void sendStreamReset(StreamStateMachine state, StreamException se) throws 
IOException {
         if (log.isDebugEnabled()) {
             log.debug(sm.getString("upgradeHandler.rst.debug", connectionId,
                     Integer.toString(se.getStreamId()), se.getError(), 
se.getMessage()));
@@ -139,9 +141,23 @@ public class Http2AsyncUpgradeHandler extends 
Http2UpgradeHandler {
         ByteUtil.set31Bits(rstFrame, 5, se.getStreamId());
         // Payload
         ByteUtil.setFourBytes(rstFrame, 9, se.getError().getCode());
-        socketWrapper.write(BlockingMode.SEMI_BLOCK, 
protocol.getWriteTimeout(),
-                TimeUnit.MILLISECONDS, null, SocketWrapperBase.COMPLETE_WRITE, 
errorCompletion,
-                ByteBuffer.wrap(rstFrame));
+
+        // Need to update state atomically with the sending of the RST
+        // frame else other threads currently working with this stream
+        // may see the state change and send a RST frame before the RST
+        // frame triggered by this thread. If that happens the client
+        // may see out of order RST frames which may hard to follow if
+        // the client is unaware the RST frames may be received out of
+        // order.
+        synchronized (sendResetLock) {
+            if (state != null) {
+                state.sendReset();
+            }
+
+            socketWrapper.write(BlockingMode.SEMI_BLOCK, 
protocol.getWriteTimeout(),
+                    TimeUnit.MILLISECONDS, null, 
SocketWrapperBase.COMPLETE_WRITE, errorCompletion,
+                    ByteBuffer.wrap(rstFrame));
+        }
         handleAsyncException();
     }
 

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

Reply via email to