Merge pull request #408 from benaadams/CancellationTokenSource

Remove CreateLinkedTokenSource
This commit is contained in:
David Fowler 2015-11-25 01:32:04 -08:00
commit ea7f40c592
1 changed files with 52 additions and 9 deletions

View File

@ -53,8 +53,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
private Task _requestProcessingTask;
private volatile bool _requestProcessingStopping; // volatile, see: https://msdn.microsoft.com/en-us/library/x13ttww7.aspx
private volatile bool _requestAborted;
private CancellationTokenSource _disconnectCts = new CancellationTokenSource();
private CancellationTokenSource _requestAbortCts;
private CancellationTokenSource _abortedCts;
private CancellationToken? _manuallySetRequestAbortToken;
private FrameRequestStream _requestBody;
private FrameResponseStream _responseBody;
@ -135,8 +135,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; }
@ -188,7 +227,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
_prepareRequest?.Invoke(this);
_requestAbortCts?.Dispose();
_manuallySetRequestAbortToken = null;
_abortedCts = null;
}
public void ResetResponseHeaders()
@ -244,13 +284,16 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{
ConnectionControl.End(ProduceEndType.SocketDisconnect);
SocketInput.AbortAwaiting();
_disconnectCts.Cancel();
RequestAbortedSource.Cancel();
}
catch (Exception ex)
{
Log.LogError("Abort", ex);
}
finally
{
_abortedCts = null;
}
}
/// <summary>
@ -294,8 +337,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
ResponseBody = _responseBody;
DuplexStream = new FrameDuplexStream(RequestBody, ResponseBody);
_requestAbortCts = CancellationTokenSource.CreateLinkedTokenSource(_disconnectCts.Token);
RequestAborted = _requestAbortCts.Token;
_abortedCts = null;
_manuallySetRequestAbortToken = null;
var httpContext = HttpContextFactory.Create(this);
try
@ -351,7 +394,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{
try
{
_disconnectCts.Dispose();
_abortedCts = null;
// If _requestAborted is set, the connection has already been closed.
if (!_requestAborted)