This is an automated email from the ASF dual-hosted git repository.
markt pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/9.0.x by this push:
new 16847e1 Fix build. Use new sendResetLock in async handler
16847e1 is described below
commit 16847e13a483f8268b9144056e621810cea1bd19
Author: Mark Thomas <[email protected]>
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 848a9e1..817402b 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: [email protected]
For additional commands, e-mail: [email protected]