Small clean up and allocation removals (#21918)
- Remove IAsyncResult implementation - Make AsyncAcceptContext derive from TaskCompletionSource
This commit is contained in:
parent
6c7a8bb397
commit
02bf53de96
|
|
@ -10,48 +10,23 @@ using Microsoft.AspNetCore.HttpSys.Internal;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Server.HttpSys
|
namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
{
|
{
|
||||||
internal unsafe class AsyncAcceptContext : IAsyncResult, IDisposable
|
internal unsafe class AsyncAcceptContext : TaskCompletionSource<RequestContext>, IDisposable
|
||||||
{
|
{
|
||||||
internal static readonly IOCompletionCallback IOCallback = new IOCompletionCallback(IOWaitCallback);
|
internal static readonly IOCompletionCallback IOCallback = new IOCompletionCallback(IOWaitCallback);
|
||||||
|
|
||||||
private TaskCompletionSource<RequestContext> _tcs;
|
|
||||||
private HttpSysListener _server;
|
|
||||||
private NativeRequestContext _nativeRequestContext;
|
private NativeRequestContext _nativeRequestContext;
|
||||||
|
|
||||||
internal AsyncAcceptContext(HttpSysListener server)
|
internal AsyncAcceptContext(HttpSysListener server)
|
||||||
{
|
{
|
||||||
_server = server;
|
Server = server;
|
||||||
_tcs = new TaskCompletionSource<RequestContext>();
|
|
||||||
AllocateNativeRequest();
|
AllocateNativeRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Task<RequestContext> Task
|
internal HttpSysListener Server { get; }
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _tcs.Task;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private TaskCompletionSource<RequestContext> Tcs
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _tcs;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal HttpSysListener Server
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _server;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Redirecting to callback")]
|
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Redirecting to callback")]
|
||||||
[SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Disposed by callback")]
|
[SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Disposed by callback")]
|
||||||
private static void IOCompleted(AsyncAcceptContext asyncResult, uint errorCode, uint numBytes)
|
private static void IOCompleted(AsyncAcceptContext asyncContext, uint errorCode, uint numBytes)
|
||||||
{
|
{
|
||||||
bool complete = false;
|
bool complete = false;
|
||||||
try
|
try
|
||||||
|
|
@ -59,28 +34,28 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
if (errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS &&
|
if (errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS &&
|
||||||
errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_MORE_DATA)
|
errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_MORE_DATA)
|
||||||
{
|
{
|
||||||
asyncResult.Tcs.TrySetException(new HttpSysException((int)errorCode));
|
asyncContext.TrySetException(new HttpSysException((int)errorCode));
|
||||||
complete = true;
|
complete = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HttpSysListener server = asyncResult.Server;
|
HttpSysListener server = asyncContext.Server;
|
||||||
if (errorCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS)
|
if (errorCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
// at this point we have received an unmanaged HTTP_REQUEST and memoryBlob
|
// at this point we have received an unmanaged HTTP_REQUEST and memoryBlob
|
||||||
// points to it we need to hook up our authentication handling code here.
|
// points to it we need to hook up our authentication handling code here.
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (server.ValidateRequest(asyncResult._nativeRequestContext) && server.ValidateAuth(asyncResult._nativeRequestContext))
|
if (server.ValidateRequest(asyncContext._nativeRequestContext) && server.ValidateAuth(asyncContext._nativeRequestContext))
|
||||||
{
|
{
|
||||||
RequestContext requestContext = new RequestContext(server, asyncResult._nativeRequestContext);
|
RequestContext requestContext = new RequestContext(server, asyncContext._nativeRequestContext);
|
||||||
asyncResult.Tcs.TrySetResult(requestContext);
|
asyncContext.TrySetResult(requestContext);
|
||||||
complete = true;
|
complete = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
server.SendError(asyncResult._nativeRequestContext.RequestId, StatusCodes.Status400BadRequest);
|
server.SendError(asyncContext._nativeRequestContext.RequestId, StatusCodes.Status400BadRequest);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
|
@ -88,30 +63,30 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
// The request has been handed to the user, which means this code can't reuse the blob. Reset it here.
|
// The request has been handed to the user, which means this code can't reuse the blob. Reset it here.
|
||||||
if (complete)
|
if (complete)
|
||||||
{
|
{
|
||||||
asyncResult._nativeRequestContext = null;
|
asyncContext._nativeRequestContext = null;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
asyncResult.AllocateNativeRequest(size: asyncResult._nativeRequestContext.Size);
|
asyncContext.AllocateNativeRequest(size: asyncContext._nativeRequestContext.Size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// (uint)backingBuffer.Length - AlignmentPadding
|
// (uint)backingBuffer.Length - AlignmentPadding
|
||||||
asyncResult.AllocateNativeRequest(numBytes, asyncResult._nativeRequestContext.RequestId);
|
asyncContext.AllocateNativeRequest(numBytes, asyncContext._nativeRequestContext.RequestId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need to issue a new request, either because auth failed, or because our buffer was too small the first time.
|
// We need to issue a new request, either because auth failed, or because our buffer was too small the first time.
|
||||||
if (!complete)
|
if (!complete)
|
||||||
{
|
{
|
||||||
uint statusCode = asyncResult.QueueBeginGetContext();
|
uint statusCode = asyncContext.QueueBeginGetContext();
|
||||||
if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS &&
|
if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS &&
|
||||||
statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_IO_PENDING)
|
statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_IO_PENDING)
|
||||||
{
|
{
|
||||||
// someother bad error, possible(?) return values are:
|
// someother bad error, possible(?) return values are:
|
||||||
// ERROR_INVALID_HANDLE, ERROR_INSUFFICIENT_BUFFER, ERROR_OPERATION_ABORTED
|
// ERROR_INVALID_HANDLE, ERROR_INSUFFICIENT_BUFFER, ERROR_OPERATION_ABORTED
|
||||||
asyncResult.Tcs.TrySetException(new HttpSysException((int)statusCode));
|
asyncContext.TrySetException(new HttpSysException((int)statusCode));
|
||||||
complete = true;
|
complete = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -123,14 +98,14 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
|
|
||||||
if (complete)
|
if (complete)
|
||||||
{
|
{
|
||||||
asyncResult.Dispose();
|
asyncContext.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
// Logged by caller
|
// Logged by caller
|
||||||
asyncResult.Tcs.TrySetException(exception);
|
asyncContext.TrySetException(exception);
|
||||||
asyncResult.Dispose();
|
asyncContext.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -199,26 +174,6 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
_nativeRequestContext = new NativeRequestContext(nativeOverlapped, Server.MemoryPool, size, requestId);
|
_nativeRequestContext = new NativeRequestContext(nativeOverlapped, Server.MemoryPool, size, requestId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public object AsyncState
|
|
||||||
{
|
|
||||||
get { return _tcs.Task.AsyncState; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public WaitHandle AsyncWaitHandle
|
|
||||||
{
|
|
||||||
get { return ((IAsyncResult)_tcs.Task).AsyncWaitHandle; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool CompletedSynchronously
|
|
||||||
{
|
|
||||||
get { return ((IAsyncResult)_tcs.Task).CompletedSynchronously; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsCompleted
|
|
||||||
{
|
|
||||||
get { return _tcs.Task.IsCompleted; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
Dispose(true);
|
Dispose(true);
|
||||||
|
|
|
||||||
|
|
@ -279,7 +279,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Task<RequestContext> AcceptAsync()
|
public Task<RequestContext> AcceptAsync()
|
||||||
{
|
{
|
||||||
AsyncAcceptContext asyncResult = null;
|
AsyncAcceptContext acceptContext = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
CheckDisposed();
|
CheckDisposed();
|
||||||
|
|
@ -287,14 +287,14 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
// prepare the ListenerAsyncResult object (this will have it's own
|
// prepare the ListenerAsyncResult object (this will have it's own
|
||||||
// event that the user can wait on for IO completion - which means we
|
// event that the user can wait on for IO completion - which means we
|
||||||
// need to signal it when IO completes)
|
// need to signal it when IO completes)
|
||||||
asyncResult = new AsyncAcceptContext(this);
|
acceptContext = new AsyncAcceptContext(this);
|
||||||
uint statusCode = asyncResult.QueueBeginGetContext();
|
uint statusCode = acceptContext.QueueBeginGetContext();
|
||||||
if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS &&
|
if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS &&
|
||||||
statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_IO_PENDING)
|
statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_IO_PENDING)
|
||||||
{
|
{
|
||||||
// some other bad error, possible(?) return values are:
|
// some other bad error, possible(?) return values are:
|
||||||
// ERROR_INVALID_HANDLE, ERROR_INSUFFICIENT_BUFFER, ERROR_OPERATION_ABORTED
|
// ERROR_INVALID_HANDLE, ERROR_INSUFFICIENT_BUFFER, ERROR_OPERATION_ABORTED
|
||||||
asyncResult.Dispose();
|
acceptContext.Dispose();
|
||||||
throw new HttpSysException((int)statusCode);
|
throw new HttpSysException((int)statusCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -304,7 +304,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
return asyncResult.Task;
|
return acceptContext.Task;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal unsafe bool ValidateRequest(NativeRequestContext requestMemory)
|
internal unsafe bool ValidateRequest(NativeRequestContext requestMemory)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue