diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2OutputProducer.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2OutputProducer.cs
index 0f95f70ef7..cc30a8ee66 100644
--- a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2OutputProducer.cs
+++ b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2OutputProducer.cs
@@ -41,10 +41,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
private bool _suffixSent;
private bool _streamEnded;
private bool _writerComplete;
- private bool _disposed;
// Internal for testing
internal ValueTask _dataWriteProcessingTask;
+ internal bool _disposed;
/// The core logic for the IValueTaskSource implementation.
private ManualResetValueTaskSourceCore _responseCompleteTaskSource = new ManualResetValueTaskSourceCore { RunContinuationsAsynchronously = true }; // mutable struct, do not make this readonly
diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2ConnectionTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2ConnectionTests.cs
index 1a7bd27c24..f7426ef669 100644
--- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2ConnectionTests.cs
+++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2ConnectionTests.cs
@@ -486,12 +486,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
withStreamId: 1);
await WaitForStreamErrorAsync(1, Http2ErrorCode.INTERNAL_ERROR, null);
- // Ping will trigger the stream to be returned to the pool so we can assert it
- await SendPingAsync(Http2PingFrameFlags.NONE);
- await ExpectAsync(Http2FrameType.PING,
- withLength: 8,
- withFlags: (byte)Http2PingFrameFlags.ACK,
- withStreamId: 0);
+ await PingUntilStreamDisposed(stream).DefaultTimeout();
// Stream is not returned to the pool
Assert.Equal(0, _connection.StreamPool.Count);
@@ -500,6 +495,21 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
await output._dataWriteProcessingTask.DefaultTimeout();
await StopConnectionAsync(expectedLastStreamId: 1, ignoreNonGoAwayFrames: false);
+
+ async Task PingUntilStreamDisposed(Http2Stream stream)
+ {
+ var output = (Http2OutputProducer)stream.Output;
+
+ do
+ {
+ // Ping will trigger the stream to be returned to the pool so we can assert it
+ await SendPingAsync(Http2PingFrameFlags.NONE);
+ await ExpectAsync(Http2FrameType.PING,
+ withLength: 8,
+ withFlags: (byte)Http2PingFrameFlags.ACK,
+ withStreamId: 0);
+ } while (!output._disposed);
+ }
}
[Fact]