Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2056,9 +2056,14 @@ private void CompleteResponse()
_connectionClose = true;
}

// If the connection is no longer in use (i.e. for NT authentication), then we can return it to the pool now.
// Otherwise, it will be returned when the connection is no longer in use (i.e. Release above is called).
if (!_inUse)
// If the connection is no longer in use (i.e. for NT authentication), then we can
// return it to the pool now; otherwise, it will be returned by the Release method later.
// The cancellation logic in HTTP/1.1 response stream reading methods is prone to race conditions
// where CancellationTokenRegistration callbacks may dispose the connection without the disposal
// leading to an actual cancellation of the response reading methods by an OperationCanceledException.
// To guard against these cases, it is necessary to check if the connection is disposed before
// attempting to return it to the pool.
if (!_inUse && !_disposed)
{
ReturnConnectionToPool();
}
Expand Down Expand Up @@ -2097,6 +2102,7 @@ public async ValueTask DrainResponseAsync(HttpResponseMessage response, Cancella

private void ReturnConnectionToPool()
{
Debug.Assert(!_disposed, "Connection should not be disposed.");
Debug.Assert(_currentRequest == null, "Connection should no longer be associated with a request.");
Debug.Assert(_readAheadTask == default, "Expected a previous initial read to already be consumed.");
Debug.Assert(_readAheadTaskStatus == ReadAheadTask_NotStarted, "Expected SendAsync to reset the read-ahead task status.");
Expand Down
Loading