Only reuse HTTP/2 streams when response writer was completed s… (#20121)

This commit is contained in:
James Newton-King 2020-03-26 18:34:53 +13:00 committed by GitHub
parent f0e6a8933c
commit 84bd089ae3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 7 additions and 16 deletions

View File

@ -86,7 +86,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
_streamEnded = false; _streamEnded = false;
_suffixSent = false; _suffixSent = false;
_suffixSent = false;
_startedWritingDataFrames = false; _startedWritingDataFrames = false;
_streamCompleted = false; _streamCompleted = false;
_writerComplete = false; _writerComplete = false;
@ -462,17 +461,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
// Stream state will move to RequestProcessingStatus.ResponseCompleted // Stream state will move to RequestProcessingStatus.ResponseCompleted
_responseCompleteTaskSource.SetResult(flushResult); _responseCompleteTaskSource.SetResult(flushResult);
if (readResult.IsCompleted) // Wait here for the stream to be reset or disposed.
{ await new ValueTask(_resetAwaitable, _resetAwaitable.Version);
// Successfully read all data. Wait here for the stream to be reset. _resetAwaitable.Reset();
await new ValueTask(_resetAwaitable, _resetAwaitable.Version);
_resetAwaitable.Reset();
}
else
{
// Stream was aborted.
break;
}
} while (!_disposed); } while (!_disposed);
static void ThrowUnexpectedState() static void ThrowUnexpectedState()
@ -537,6 +528,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
} }
_disposed = true; _disposed = true;
// Set awaitable after disposed is true to ensure ProcessDataWrites exits successfully.
_resetAwaitable.SetResult(null); _resetAwaitable.SetResult(null);
} }
} }

View File

@ -156,10 +156,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
// connection's flow-control window. // connection's flow-control window.
_inputFlowControl.Abort(); _inputFlowControl.Abort();
// We only want to reuse a stream that has completely finished writing. // We only want to reuse a stream that was not aborted and has completely finished writing.
// This is to prevent the situation where Http2OutputProducer.ProcessDataWrites // This ensures Http2OutputProducer.ProcessDataWrites is in the correct state to be reused.
// is still running in the background. CanReuse = !_connectionAborted && HasResponseCompleted;
CanReuse = !_keepAlive && HasResponseCompleted;
} }
finally finally
{ {