Merge pull request #3 from stephentoub/delay_cts_allocation
Lazily allocate the RequestAborted CTS
This commit is contained in:
commit
16cccb50cb
|
|
@ -44,6 +44,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
private volatile bool _requestProcessingStopping; // volatile, see: https://msdn.microsoft.com/en-us/library/x13ttww7.aspx
|
||||
private volatile bool _requestAborted;
|
||||
private CancellationTokenSource _abortedCts;
|
||||
private CancellationToken? _manuallySetRequestAbortToken;
|
||||
|
||||
private FrameRequestStream _requestBody;
|
||||
private FrameResponseStream _responseBody;
|
||||
|
|
@ -92,8 +93,47 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
|
||||
public Stream DuplexStream { get; set; }
|
||||
|
||||
public CancellationToken RequestAborted { get; set; }
|
||||
public CancellationToken RequestAborted
|
||||
{
|
||||
get
|
||||
{
|
||||
// If a request abort token was previously explicitly set, return it.
|
||||
if (_manuallySetRequestAbortToken.HasValue)
|
||||
return _manuallySetRequestAbortToken.Value;
|
||||
|
||||
// Otherwise, get the abort CTS. If we have one, which would mean that someone previously
|
||||
// asked for the RequestAborted token, simply return its token. If we don't,
|
||||
// check to see whether we've already aborted, in which case just return an
|
||||
// already canceled token. Finally, force a source into existence if we still
|
||||
// don't have one, and return its token.
|
||||
var cts = _abortedCts;
|
||||
return
|
||||
cts != null ? cts.Token :
|
||||
_requestAborted ? new CancellationToken(true) :
|
||||
RequestAbortedSource.Token;
|
||||
}
|
||||
set
|
||||
{
|
||||
// Set an abort token, overriding one we create internally. This setter and associated
|
||||
// field exist purely to support IHttpRequestLifetimeFeature.set_RequestAborted.
|
||||
_manuallySetRequestAbortToken = value;
|
||||
}
|
||||
}
|
||||
|
||||
private CancellationTokenSource RequestAbortedSource
|
||||
{
|
||||
get
|
||||
{
|
||||
// Get the abort token, lazily-initializing it if necessary.
|
||||
// Make sure it's canceled if an abort request already came in.
|
||||
var cts = LazyInitializer.EnsureInitialized(ref _abortedCts, () => new CancellationTokenSource());
|
||||
if (_requestAborted)
|
||||
{
|
||||
cts.Cancel();
|
||||
}
|
||||
return cts;
|
||||
}
|
||||
}
|
||||
public bool HasResponseStarted
|
||||
{
|
||||
get { return _responseStarted; }
|
||||
|
|
@ -145,7 +185,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
|
||||
_prepareRequest?.Invoke(this);
|
||||
|
||||
_abortedCts?.Dispose();
|
||||
_manuallySetRequestAbortToken = null;
|
||||
_abortedCts = null;
|
||||
}
|
||||
|
||||
|
|
@ -198,16 +238,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
{
|
||||
ConnectionControl.End(ProduceEndType.SocketDisconnect);
|
||||
SocketInput.AbortAwaiting();
|
||||
|
||||
try
|
||||
{
|
||||
_abortedCts?.Cancel();
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
// Don't log ODEs thrown from _abortedCts.Cancel()
|
||||
// If _abortedCts is disposed, the app has already completed.
|
||||
}
|
||||
RequestAbortedSource.Cancel();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -215,7 +246,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
}
|
||||
finally
|
||||
{
|
||||
_abortedCts?.Dispose();
|
||||
_abortedCts = null;
|
||||
}
|
||||
}
|
||||
|
|
@ -261,8 +291,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
ResponseBody = _responseBody;
|
||||
DuplexStream = new FrameDuplexStream(RequestBody, ResponseBody);
|
||||
|
||||
_abortedCts = new CancellationTokenSource();
|
||||
RequestAborted = _abortedCts.Token;
|
||||
_abortedCts = null;
|
||||
_manuallySetRequestAbortToken = null;
|
||||
|
||||
var httpContext = HttpContextFactory.Create(this);
|
||||
try
|
||||
|
|
@ -315,7 +345,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
{
|
||||
try
|
||||
{
|
||||
_abortedCts?.Dispose();
|
||||
_abortedCts = null;
|
||||
|
||||
// If _requestAborted is set, the connection has already been closed.
|
||||
|
|
|
|||
Loading…
Reference in New Issue