Skip to content

Commit d4cf305

Browse files
committed
8373409: java/net/httpclient/http3/H3ErrorHandlingTest.java failed due to deadlock
Reviewed-by: dfuchs Backport-of: 386ad61
1 parent 509ca63 commit d4cf305

File tree

2 files changed

+31
-36
lines changed

2 files changed

+31
-36
lines changed

src/java.net.http/share/classes/jdk/internal/net/http/quic/QuicEndpoint.java

Lines changed: 30 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1581,34 +1581,30 @@ private void remapPeerIssuedResetToken(QuicPacketReceiver from, QuicPacketReceiv
15811581
peerIssuedResetTokens.replaceAll((tok, c) -> c == from ? to : c);
15821582
}
15831583

1584-
public void draining(final QuicPacketReceiver connection) {
1584+
public void draining(final QuicConnectionImpl connection) {
15851585
// remap the connection to a DrainingConnection
15861586
if (closed) return;
1587+
1588+
final long idleTimeout = connection.peerPtoMs() * 3; // 3 PTO
1589+
connection.localConnectionIdManager().close();
1590+
DrainingConnection draining = new DrainingConnection(connection.connectionIds(), idleTimeout);
1591+
// we can ignore stateless reset in the draining state.
1592+
remapPeerIssuedResetToken(connection, draining);
1593+
15871594
connection.connectionIds().forEach((id) ->
1588-
connections.compute(id, this::remapDraining));
1595+
connections.compute(id, (i, r) -> remapDraining(i, r, draining)));
1596+
draining.startTimer();
15891597
assert !connections.containsValue(connection) : connection;
15901598
}
15911599

1592-
private DrainingConnection remapDraining(QuicConnectionId id, QuicPacketReceiver conn) {
1600+
private DrainingConnection remapDraining(QuicConnectionId id, QuicPacketReceiver conn, DrainingConnection draining) {
15931601
if (closed) return null;
15941602
var debugOn = debug.on() && !Thread.currentThread().isVirtual();
1595-
if (conn instanceof ClosingConnection closing) {
1603+
if (conn instanceof QuicConnectionImpl || conn instanceof ClosingConnection) {
15961604
if (debugOn) debug.log("remapping %s to DrainingConnection", id);
1597-
final var draining = closing.toDraining();
1598-
remapPeerIssuedResetToken(closing, draining);
1599-
draining.startTimer();
1600-
return draining;
1601-
} else if (conn instanceof DrainingConnection draining) {
1602-
return draining;
1603-
} else if (conn instanceof QuicConnectionImpl impl) {
1604-
final long idleTimeout = impl.peerPtoMs() * 3; // 3 PTO
1605-
impl.localConnectionIdManager().close();
1606-
if (debugOn) debug.log("remapping %s to DrainingConnection", id);
1607-
var draining = new DrainingConnection(conn.connectionIds(), idleTimeout);
1608-
// we can ignore stateless reset in the draining state.
1609-
remapPeerIssuedResetToken(impl, draining);
1610-
draining.startTimer();
16111605
return draining;
1606+
} else if (conn instanceof DrainingConnection d) {
1607+
return d;
16121608
} else if (conn == null) {
16131609
// connection absent (was probably removed), don't remap to draining
16141610
if (debugOn) {
@@ -1623,30 +1619,32 @@ private DrainingConnection remapDraining(QuicConnectionId id, QuicPacketReceiver
16231619

16241620
protected void closing(QuicConnectionImpl connection, ByteBuffer datagram) {
16251621
if (closed) return;
1626-
ByteBuffer closing = ByteBuffer.allocate(datagram.limit());
1627-
closing.put(datagram.slice());
1628-
closing.flip();
1622+
ByteBuffer closingDatagram = ByteBuffer.allocate(datagram.limit());
1623+
closingDatagram.put(datagram.slice());
1624+
closingDatagram.flip();
1625+
1626+
final long idleTimeout = connection.peerPtoMs() * 3; // 3 PTO
1627+
connection.localConnectionIdManager().close();
1628+
var closingConnection = new ClosingConnection(connection.connectionIds(), idleTimeout, datagram);
1629+
remapPeerIssuedResetToken(connection, closingConnection);
1630+
16291631
connection.connectionIds().forEach((id) ->
1630-
connections.compute(id, (i, r) -> remapClosing(i, r, closing)));
1632+
connections.compute(id, (i, r) -> remapClosing(i, r, closingConnection)));
1633+
closingConnection.startTimer();
16311634
assert !connections.containsValue(connection) : connection;
16321635
}
16331636

1634-
private ClosedConnection remapClosing(QuicConnectionId id, QuicPacketReceiver conn, ByteBuffer datagram) {
1637+
private ClosedConnection remapClosing(QuicConnectionId id, QuicPacketReceiver conn, ClosingConnection closingConnection) {
16351638
if (closed) return null;
16361639
var debugOn = debug.on() && !Thread.currentThread().isVirtual();
1637-
if (conn instanceof ClosingConnection closing) {
1640+
if (conn instanceof QuicConnectionImpl) {
1641+
if (debugOn) debug.log("remapping %s to ClosingConnection", id);
1642+
return closingConnection;
1643+
} else if (conn instanceof ClosingConnection closing) {
16381644
// we already have a closing datagram, drop the new one
16391645
return closing;
16401646
} else if (conn instanceof DrainingConnection draining) {
16411647
return draining;
1642-
} else if (conn instanceof QuicConnectionImpl impl) {
1643-
final long idleTimeout = impl.peerPtoMs() * 3; // 3 PTO
1644-
impl.localConnectionIdManager().close();
1645-
if (debugOn) debug.log("remapping %s to ClosingConnection", id);
1646-
var closing = new ClosingConnection(conn.connectionIds(), idleTimeout, datagram);
1647-
remapPeerIssuedResetToken(impl, closing);
1648-
closing.startTimer();
1649-
return closing;
16501648
} else if (conn == null) {
16511649
// connection absent (was probably removed), don't remap to closing
16521650
if (debugOn) {
@@ -1896,10 +1894,6 @@ protected void dropIncoming(SocketAddress source, ByteBuffer idbytes, HeadersTyp
18961894
debug.log("ClosingConnection(%s): dropping %s packet", localConnectionIds, headersType);
18971895
}
18981896
}
1899-
1900-
private DrainingConnection toDraining() {
1901-
return new DrainingConnection(localConnectionIds, maxIdleTimeMs);
1902-
}
19031897
}
19041898

19051899
/**

test/jdk/java/net/httpclient/http3/H3ErrorHandlingTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171

7272
/*
7373
* @test
74+
* @bug 8373409
7475
* @key intermittent
7576
* @comment testResetControlStream may fail if the client doesn't read the stream type
7677
* before the stream is reset,

0 commit comments

Comments
 (0)