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