Skip to content

Commit 0622513

Browse files
authored
Wait to dispose RequestAborted CTS (#4447)
1 parent 180f735 commit 0622513

File tree

3 files changed

+41
-21
lines changed

3 files changed

+41
-21
lines changed

eng/PatchConfig.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ Later on, this will be checked using this condition:
3333
Microsoft.AspNetCore.Http;
3434
Microsoft.AspNetCore.Mvc.Core;
3535
Microsoft.AspNetCore.Server.IIS;
36+
Microsoft.AspNetCore.Server.Kestrel.Core;
3637
java:signalr;
3738
</PackagesInPatch>
3839
</PropertyGroup>

src/Servers/Kestrel/Core/src/Internal/Http/HttpProtocol.cs

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -348,11 +348,8 @@ public void Reset()
348348
// Lock to prevent CancelRequestAbortedToken from attempting to cancel an disposed CTS.
349349
lock (_abortLock)
350350
{
351-
if (!_requestAborted)
352-
{
353-
_abortedCts?.Dispose();
354-
_abortedCts = null;
355-
}
351+
_abortedCts?.Dispose();
352+
_abortedCts = null;
356353
}
357354

358355
_requestHeadersParsed = 0;
@@ -394,15 +391,16 @@ protected virtual bool BeginRead(out ValueTask<ReadResult> awaitable)
394391

395392
private void CancelRequestAbortedToken()
396393
{
397-
try
398-
{
399-
_abortedCts.Cancel();
400-
_abortedCts.Dispose();
401-
_abortedCts = null;
402-
}
403-
catch (Exception ex)
394+
lock (_abortLock)
404395
{
405-
Log.ApplicationError(ConnectionId, TraceIdentifier, ex);
396+
try
397+
{
398+
_abortedCts?.Cancel();
399+
}
400+
catch (Exception ex)
401+
{
402+
Log.ApplicationError(ConnectionId, TraceIdentifier, ex);
403+
}
406404
}
407405
}
408406

@@ -416,12 +414,12 @@ protected void AbortRequest()
416414
}
417415

418416
_requestAborted = true;
419-
}
420417

421-
if (_abortedCts != null)
422-
{
423-
// Potentially calling user code. CancelRequestAbortedToken logs any exceptions.
424-
ServiceContext.Scheduler.Schedule(state => ((HttpProtocol)state).CancelRequestAbortedToken(), this);
418+
if (_abortedCts != null && !_preventRequestAbortedCancellation)
419+
{
420+
// Potentially calling user code. CancelRequestAbortedToken logs any exceptions.
421+
ServiceContext.Scheduler.Schedule(state => ((HttpProtocol)state).CancelRequestAbortedToken(), this);
422+
}
425423
}
426424
}
427425

@@ -441,8 +439,6 @@ private void PreventRequestAbortedCancellation()
441439
}
442440

443441
_preventRequestAbortedCancellation = true;
444-
_abortedCts?.Dispose();
445-
_abortedCts = null;
446442
}
447443
}
448444

src/Servers/Kestrel/Core/test/Http1ConnectionTests.cs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,11 @@ public Http1ConnectionTests()
5353
var connectionFeatures = new FeatureCollection();
5454
connectionFeatures.Set(Mock.Of<IConnectionLifetimeFeature>());
5555

56-
_serviceContext = new TestServiceContext();
56+
_serviceContext = new TestServiceContext()
57+
{
58+
Scheduler = PipeScheduler.Inline
59+
};
60+
5761
_timeoutControl = new Mock<ITimeoutControl>();
5862
_http1ConnectionContext = new HttpConnectionContext
5963
{
@@ -724,6 +728,25 @@ public async Task RequestAbortedTokenIsResetBeforeLastWriteWithChunkedEncoding()
724728
Assert.False(_http1Connection.RequestAborted.IsCancellationRequested);
725729
}
726730

731+
[Fact]
732+
public void RequestAbortedTokenIsFullyUsableAfterCancellation()
733+
{
734+
var originalToken = _http1Connection.RequestAborted;
735+
var originalRegistration = originalToken.Register(() => { });
736+
737+
_http1Connection.Abort(new ConnectionAbortedException());
738+
739+
Assert.True(originalToken.WaitHandle.WaitOne(TestConstants.DefaultTimeout));
740+
Assert.True(_http1Connection.RequestAborted.WaitHandle.WaitOne(TestConstants.DefaultTimeout));
741+
742+
#if NETCOREAPP2_2
743+
Assert.Equal(originalToken, originalRegistration.Token);
744+
#elif NET461
745+
#else
746+
#error Target framework needs to be updated
747+
#endif
748+
}
749+
727750
[Fact]
728751
public async Task ExceptionDetailNotIncludedWhenLogLevelInformationNotEnabled()
729752
{

0 commit comments

Comments
 (0)