Fire OnStreamCompleted after all pipes are closed
This commit is contained in:
parent
aa9dde2457
commit
6f7a841374
|
|
@ -63,14 +63,21 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
|
|||
|
||||
protected override void OnRequestProcessingEnded()
|
||||
{
|
||||
TryApplyCompletionFlag(StreamCompletionFlags.RequestProcessingEnded);
|
||||
var states = ApplyCompletionFlag(StreamCompletionFlags.RequestProcessingEnded);
|
||||
|
||||
try
|
||||
{
|
||||
RequestBodyPipe.Reader.Complete();
|
||||
|
||||
// The app can no longer read any more of the request body, so return any bytes that weren't read to the
|
||||
// connection's flow-control window.
|
||||
_inputFlowControl.Abort();
|
||||
}
|
||||
finally
|
||||
{
|
||||
TryFireOnStreamCompleted(states);
|
||||
}
|
||||
}
|
||||
|
||||
protected override string CreateRequestId()
|
||||
=> StringUtilities.ConcatAsHexSuffix(ConnectionId, ':', (uint)StreamId);
|
||||
|
|
@ -335,12 +342,19 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
|
|||
}
|
||||
}
|
||||
|
||||
TryApplyCompletionFlag(StreamCompletionFlags.EndStreamReceived);
|
||||
var states = ApplyCompletionFlag(StreamCompletionFlags.EndStreamReceived);
|
||||
|
||||
try
|
||||
{
|
||||
RequestBodyPipe.Writer.Complete();
|
||||
|
||||
_inputFlowControl.StopWindowUpdates();
|
||||
}
|
||||
finally
|
||||
{
|
||||
TryFireOnStreamCompleted(states);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnDataRead(int bytesRead)
|
||||
{
|
||||
|
|
@ -354,13 +368,22 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
|
|||
|
||||
public void Abort(IOException abortReason)
|
||||
{
|
||||
if (!TryApplyCompletionFlag(StreamCompletionFlags.Aborted))
|
||||
var states = ApplyCompletionFlag(StreamCompletionFlags.Aborted);
|
||||
|
||||
try
|
||||
{
|
||||
if (states.OldState == states.NewState)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AbortCore(abortReason);
|
||||
}
|
||||
finally
|
||||
{
|
||||
TryFireOnStreamCompleted(states);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnErrorAfterResponseStarted()
|
||||
{
|
||||
|
|
@ -377,11 +400,15 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
|
|||
|
||||
private void ResetAndAbort(ConnectionAbortedException abortReason, Http2ErrorCode error)
|
||||
{
|
||||
if (!TryApplyCompletionFlag(StreamCompletionFlags.Aborted))
|
||||
var states = ApplyCompletionFlag(StreamCompletionFlags.Aborted);
|
||||
|
||||
if (states.OldState == states.NewState)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Log.Http2StreamResetAbort(TraceIdentifier, error, abortReason);
|
||||
|
||||
// Don't block on IO. This never faults.
|
||||
|
|
@ -389,6 +416,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
|
|||
|
||||
AbortCore(abortReason);
|
||||
}
|
||||
finally
|
||||
{
|
||||
TryFireOnStreamCompleted(states);
|
||||
}
|
||||
}
|
||||
|
||||
private void AbortCore(Exception abortReason)
|
||||
{
|
||||
|
|
@ -415,19 +447,22 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
|
|||
minimumSegmentSize: KestrelMemoryPool.MinimumSegmentSize
|
||||
));
|
||||
|
||||
private bool TryApplyCompletionFlag(StreamCompletionFlags completionState)
|
||||
private (StreamCompletionFlags OldState, StreamCompletionFlags NewState) ApplyCompletionFlag(StreamCompletionFlags completionState)
|
||||
{
|
||||
lock (_completionLock)
|
||||
{
|
||||
var lastCompletionState = _completionState;
|
||||
var oldCompletionState = _completionState;
|
||||
_completionState |= completionState;
|
||||
|
||||
if (ShouldStopTrackingStream(_completionState) && !ShouldStopTrackingStream(lastCompletionState))
|
||||
{
|
||||
_context.StreamLifetimeHandler.OnStreamCompleted(StreamId);
|
||||
return (oldCompletionState, _completionState);
|
||||
}
|
||||
}
|
||||
|
||||
return _completionState != lastCompletionState;
|
||||
private void TryFireOnStreamCompleted((StreamCompletionFlags OldState, StreamCompletionFlags NewState) states)
|
||||
{
|
||||
if (!ShouldStopTrackingStream(states.OldState) && ShouldStopTrackingStream(states.NewState))
|
||||
{
|
||||
_context.StreamLifetimeHandler.OnStreamCompleted(StreamId);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue