Merge branch 'release' into dev
This commit is contained in:
Коммит
0acb8f3ed4
|
@ -60,7 +60,7 @@ namespace Microsoft.Net.Http.Server
|
|||
}
|
||||
}
|
||||
|
||||
private WebListener Server
|
||||
internal WebListener Server
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -152,9 +152,7 @@ namespace Microsoft.Net.Http.Server
|
|||
private static unsafe void IOWaitCallback(uint errorCode, uint numBytes, NativeOverlapped* nativeOverlapped)
|
||||
{
|
||||
// take the ListenerAsyncResult object from the state
|
||||
Overlapped callbackOverlapped = Overlapped.Unpack(nativeOverlapped);
|
||||
AsyncAcceptContext asyncResult = (AsyncAcceptContext)callbackOverlapped.AsyncResult;
|
||||
|
||||
var asyncResult = (AsyncAcceptContext)ThreadPoolBoundHandle.GetNativeOverlappedState(nativeOverlapped);
|
||||
IOCompleted(asyncResult, errorCode, numBytes);
|
||||
}
|
||||
|
||||
|
|
|
@ -30,21 +30,18 @@ namespace Microsoft.Net.Http.Server
|
|||
internal class SafeNativeOverlapped : SafeHandle
|
||||
{
|
||||
internal static readonly SafeNativeOverlapped Zero = new SafeNativeOverlapped();
|
||||
private ThreadPoolBoundHandle _boundHandle;
|
||||
|
||||
internal SafeNativeOverlapped()
|
||||
: this(IntPtr.Zero)
|
||||
{
|
||||
}
|
||||
|
||||
internal unsafe SafeNativeOverlapped(NativeOverlapped* handle)
|
||||
: this((IntPtr)handle)
|
||||
{
|
||||
}
|
||||
|
||||
internal SafeNativeOverlapped(IntPtr handle)
|
||||
: base(IntPtr.Zero, true)
|
||||
{
|
||||
SetHandle(handle);
|
||||
}
|
||||
|
||||
internal unsafe SafeNativeOverlapped(ThreadPoolBoundHandle boundHandle, NativeOverlapped* handle)
|
||||
: base(IntPtr.Zero, true)
|
||||
{
|
||||
SetHandle((IntPtr)handle);
|
||||
_boundHandle = boundHandle;
|
||||
}
|
||||
|
||||
public override bool IsInvalid
|
||||
|
@ -76,7 +73,7 @@ namespace Microsoft.Net.Http.Server
|
|||
{
|
||||
unsafe
|
||||
{
|
||||
Overlapped.Free((NativeOverlapped*)oldHandle);
|
||||
_boundHandle.FreeNativeOverlapped((NativeOverlapped*)oldHandle);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
#if !DNXCORE50 // TODO: Temp copy. Remove once we target net46.
|
||||
using System;
|
||||
namespace System.Threading
|
||||
{
|
||||
internal struct DeferredDisposableLifetime<T> where T : class, IDeferredDisposable
|
||||
{
|
||||
private int _count;
|
||||
public bool AddRef(T obj)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
int num = Volatile.Read(ref this._count);
|
||||
if (num < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
int num2 = checked(num + 1);
|
||||
if (Interlocked.CompareExchange(ref this._count, num2, num) == num)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
throw new ObjectDisposedException(typeof(T).ToString());
|
||||
}
|
||||
public void Release(T obj)
|
||||
{
|
||||
int num2;
|
||||
int num3;
|
||||
while (true)
|
||||
{
|
||||
int num = Volatile.Read(ref this._count);
|
||||
if (num > 0)
|
||||
{
|
||||
num2 = num - 1;
|
||||
if (Interlocked.CompareExchange(ref this._count, num2, num) == num)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
num3 = num + 1;
|
||||
if (Interlocked.CompareExchange(ref this._count, num3, num) == num)
|
||||
{
|
||||
goto Block_3;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (num2 == 0)
|
||||
{
|
||||
obj.OnFinalRelease(false);
|
||||
}
|
||||
return;
|
||||
Block_3:
|
||||
if (num3 == -1)
|
||||
{
|
||||
obj.OnFinalRelease(true);
|
||||
}
|
||||
}
|
||||
public void Dispose(T obj)
|
||||
{
|
||||
int num2;
|
||||
while (true)
|
||||
{
|
||||
int num = Volatile.Read(ref this._count);
|
||||
if (num < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
num2 = -1 - num;
|
||||
if (Interlocked.CompareExchange(ref this._count, num2, num) == num)
|
||||
{
|
||||
goto Block_1;
|
||||
}
|
||||
}
|
||||
return;
|
||||
Block_1:
|
||||
if (num2 == -1)
|
||||
{
|
||||
obj.OnFinalRelease(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,10 @@
|
|||
#if !DNXCORE50 // TODO: Temp copy. Remove once we target net46.
|
||||
using System;
|
||||
namespace System.Threading
|
||||
{
|
||||
internal interface IDeferredDisposable
|
||||
{
|
||||
void OnFinalRelease(bool disposed);
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,51 @@
|
|||
#if !DNXCORE50 // TODO: Temp copy. Remove once we target net46.
|
||||
using System;
|
||||
namespace System.Threading
|
||||
{
|
||||
public sealed class PreAllocatedOverlapped : IDisposable, IDeferredDisposable
|
||||
{
|
||||
internal readonly ThreadPoolBoundHandleOverlapped _overlapped;
|
||||
private DeferredDisposableLifetime<PreAllocatedOverlapped> _lifetime;
|
||||
[CLSCompliant(false)]
|
||||
public PreAllocatedOverlapped(IOCompletionCallback callback, object state, object pinData)
|
||||
{
|
||||
if (callback == null)
|
||||
{
|
||||
throw new ArgumentNullException("callback");
|
||||
}
|
||||
this._overlapped = new ThreadPoolBoundHandleOverlapped(callback, state, pinData, this);
|
||||
}
|
||||
internal bool AddRef()
|
||||
{
|
||||
return this._lifetime.AddRef(this);
|
||||
}
|
||||
internal void Release()
|
||||
{
|
||||
this._lifetime.Release(this);
|
||||
}
|
||||
public void Dispose()
|
||||
{
|
||||
this._lifetime.Dispose(this);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
~PreAllocatedOverlapped()
|
||||
{
|
||||
if (!Environment.HasShutdownStarted)
|
||||
{
|
||||
this.Dispose();
|
||||
}
|
||||
}
|
||||
unsafe void IDeferredDisposable.OnFinalRelease(bool disposed)
|
||||
{
|
||||
if (disposed)
|
||||
{
|
||||
Overlapped.Free(this._overlapped._nativeOverlapped);
|
||||
return;
|
||||
}
|
||||
this._overlapped._boundHandle = null;
|
||||
this._overlapped._completed = false;
|
||||
*this._overlapped._nativeOverlapped = default(NativeOverlapped);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,143 @@
|
|||
#if !DNXCORE50 // TODO: Temp copy. Remove once we target net46.
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
namespace System.Threading
|
||||
{
|
||||
public sealed class ThreadPoolBoundHandle : IDisposable
|
||||
{
|
||||
private readonly SafeHandle _handle;
|
||||
private bool _isDisposed;
|
||||
public SafeHandle Handle
|
||||
{
|
||||
get
|
||||
{
|
||||
return this._handle;
|
||||
}
|
||||
}
|
||||
private ThreadPoolBoundHandle(SafeHandle handle)
|
||||
{
|
||||
this._handle = handle;
|
||||
}
|
||||
public static ThreadPoolBoundHandle BindHandle(SafeHandle handle)
|
||||
{
|
||||
if (handle == null)
|
||||
{
|
||||
throw new ArgumentNullException("handle");
|
||||
}
|
||||
if (handle.IsClosed || handle.IsInvalid)
|
||||
{
|
||||
throw new ArgumentException("Invalid Handle", "handle");
|
||||
}
|
||||
try
|
||||
{
|
||||
ThreadPool.BindHandle(handle);
|
||||
}
|
||||
catch (Exception expr_38)
|
||||
{
|
||||
if (expr_38.HResult == -2147024890)
|
||||
{
|
||||
throw new ArgumentException("Invalid Handle", "handle");
|
||||
}
|
||||
if (expr_38.HResult == -2147024809)
|
||||
{
|
||||
throw new ArgumentException("Already Bound", "handle");
|
||||
}
|
||||
throw;
|
||||
}
|
||||
return new ThreadPoolBoundHandle(handle);
|
||||
}
|
||||
[CLSCompliant(false)]
|
||||
public unsafe NativeOverlapped* AllocateNativeOverlapped(IOCompletionCallback callback, object state, object pinData)
|
||||
{
|
||||
if (callback == null)
|
||||
{
|
||||
throw new ArgumentNullException("callback");
|
||||
}
|
||||
this.EnsureNotDisposed();
|
||||
return new ThreadPoolBoundHandleOverlapped(callback, state, pinData, null)
|
||||
{
|
||||
_boundHandle = this
|
||||
}._nativeOverlapped;
|
||||
}
|
||||
[CLSCompliant(false)]
|
||||
public unsafe NativeOverlapped* AllocateNativeOverlapped(PreAllocatedOverlapped preAllocated)
|
||||
{
|
||||
if (preAllocated == null)
|
||||
{
|
||||
throw new ArgumentNullException("preAllocated");
|
||||
}
|
||||
this.EnsureNotDisposed();
|
||||
preAllocated.AddRef();
|
||||
NativeOverlapped* nativeOverlapped;
|
||||
try
|
||||
{
|
||||
ThreadPoolBoundHandleOverlapped expr_21 = preAllocated._overlapped;
|
||||
if (expr_21._boundHandle != null)
|
||||
{
|
||||
throw new ArgumentException("Already Allocated", "preAllocated");
|
||||
}
|
||||
expr_21._boundHandle = this;
|
||||
nativeOverlapped = expr_21._nativeOverlapped;
|
||||
}
|
||||
catch
|
||||
{
|
||||
preAllocated.Release();
|
||||
throw;
|
||||
}
|
||||
return nativeOverlapped;
|
||||
}
|
||||
[CLSCompliant(false)]
|
||||
public unsafe void FreeNativeOverlapped(NativeOverlapped* overlapped)
|
||||
{
|
||||
if (overlapped == null)
|
||||
{
|
||||
throw new ArgumentNullException("overlapped");
|
||||
}
|
||||
ThreadPoolBoundHandleOverlapped overlappedWrapper = ThreadPoolBoundHandle.GetOverlappedWrapper(overlapped, this);
|
||||
if (overlappedWrapper._boundHandle != this)
|
||||
{
|
||||
throw new ArgumentException("Wrong bound handle", "overlapped");
|
||||
}
|
||||
if (overlappedWrapper._preAllocated != null)
|
||||
{
|
||||
overlappedWrapper._preAllocated.Release();
|
||||
return;
|
||||
}
|
||||
Overlapped.Free(overlapped);
|
||||
}
|
||||
[CLSCompliant(false)]
|
||||
public unsafe static object GetNativeOverlappedState(NativeOverlapped* overlapped)
|
||||
{
|
||||
if (overlapped == null)
|
||||
{
|
||||
throw new ArgumentNullException("overlapped");
|
||||
}
|
||||
return ThreadPoolBoundHandle.GetOverlappedWrapper(overlapped, null)._userState;
|
||||
}
|
||||
private unsafe static ThreadPoolBoundHandleOverlapped GetOverlappedWrapper(NativeOverlapped* overlapped, ThreadPoolBoundHandle expectedBoundHandle)
|
||||
{
|
||||
ThreadPoolBoundHandleOverlapped result;
|
||||
try
|
||||
{
|
||||
result = (ThreadPoolBoundHandleOverlapped)Overlapped.Unpack(overlapped);
|
||||
}
|
||||
catch (NullReferenceException ex)
|
||||
{
|
||||
throw new ArgumentException("Already freed", "overlapped", ex);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
public void Dispose()
|
||||
{
|
||||
this._isDisposed = true;
|
||||
}
|
||||
private void EnsureNotDisposed()
|
||||
{
|
||||
if (this._isDisposed)
|
||||
{
|
||||
throw new ObjectDisposedException(base.GetType().ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,38 @@
|
|||
#if !DNXCORE50 // TODO: Temp copy. Remove once we target net46.
|
||||
using System;
|
||||
namespace System.Threading
|
||||
{
|
||||
internal sealed class ThreadPoolBoundHandleOverlapped : Overlapped
|
||||
{
|
||||
private readonly IOCompletionCallback _userCallback;
|
||||
internal readonly object _userState;
|
||||
internal PreAllocatedOverlapped _preAllocated;
|
||||
internal unsafe NativeOverlapped* _nativeOverlapped;
|
||||
internal ThreadPoolBoundHandle _boundHandle;
|
||||
internal bool _completed;
|
||||
public unsafe ThreadPoolBoundHandleOverlapped(IOCompletionCallback callback, object state, object pinData, PreAllocatedOverlapped preAllocated)
|
||||
{
|
||||
this._userCallback = callback;
|
||||
this._userState = state;
|
||||
this._preAllocated = preAllocated;
|
||||
this._nativeOverlapped = base.Pack(new IOCompletionCallback(ThreadPoolBoundHandleOverlapped.CompletionCallback), pinData);
|
||||
this._nativeOverlapped->OffsetLow = 0;
|
||||
this._nativeOverlapped->OffsetHigh = 0;
|
||||
}
|
||||
private unsafe static void CompletionCallback(uint errorCode, uint numBytes, NativeOverlapped* nativeOverlapped)
|
||||
{
|
||||
ThreadPoolBoundHandleOverlapped expr_0B = (ThreadPoolBoundHandleOverlapped)Overlapped.Unpack(nativeOverlapped);
|
||||
if (expr_0B._completed)
|
||||
{
|
||||
throw new InvalidOperationException("Native Overlapped reused");
|
||||
}
|
||||
expr_0B._completed = true;
|
||||
if (expr_0B._boundHandle == null)
|
||||
{
|
||||
throw new InvalidOperationException("Already freed");
|
||||
}
|
||||
expr_0B._userCallback.Invoke(errorCode, numBytes, nativeOverlapped);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -138,9 +138,9 @@ namespace Microsoft.Net.Http.Server
|
|||
return;
|
||||
}
|
||||
_backingBuffer = new byte[checked((int)size)];
|
||||
Overlapped overlapped = new Overlapped();
|
||||
overlapped.AsyncResult = this;
|
||||
_overlapped = new SafeNativeOverlapped(overlapped.Pack(IOCallback, _backingBuffer));
|
||||
var boundHandle = RequestContext.Server.BoundHandle;
|
||||
_overlapped = new SafeNativeOverlapped(boundHandle,
|
||||
boundHandle.AllocateNativeOverlapped(IOCallback, this, _backingBuffer));
|
||||
_memoryBlob = (UnsafeNclNativeMethods.HttpApi.HTTP_SSL_CLIENT_CERT_INFO*)Marshal.UnsafeAddrOfPinnedArrayElement(_backingBuffer, 0);
|
||||
}
|
||||
|
||||
|
@ -315,9 +315,7 @@ namespace Microsoft.Net.Http.Server
|
|||
|
||||
private static unsafe void WaitCallback(uint errorCode, uint numBytes, NativeOverlapped* nativeOverlapped)
|
||||
{
|
||||
Overlapped callbackOverlapped = Overlapped.Unpack(nativeOverlapped);
|
||||
ClientCertLoader asyncResult = (ClientCertLoader)callbackOverlapped.AsyncResult;
|
||||
|
||||
var asyncResult = (ClientCertLoader)ThreadPoolBoundHandle.GetNativeOverlappedState(nativeOverlapped);
|
||||
IOCompleted(asyncResult, errorCode, numBytes);
|
||||
}
|
||||
|
||||
|
|
|
@ -161,7 +161,8 @@ namespace Microsoft.Net.Http.Server
|
|||
private UnsafeNclNativeMethods.HttpApi.HTTP_REQUEST* Allocate(uint size)
|
||||
{
|
||||
uint newSize = size != 0 ? size : RequestBuffer == null ? DefaultBufferSize : Size;
|
||||
if (_nativeOverlapped != null && newSize != RequestBuffer.Length)
|
||||
// We can't reuse overlapped objects
|
||||
if (_nativeOverlapped != null)
|
||||
{
|
||||
SafeNativeOverlapped nativeOverlapped = _nativeOverlapped;
|
||||
_nativeOverlapped = null;
|
||||
|
@ -170,9 +171,9 @@ namespace Microsoft.Net.Http.Server
|
|||
if (_nativeOverlapped == null)
|
||||
{
|
||||
SetBuffer(checked((int)newSize));
|
||||
Overlapped overlapped = new Overlapped();
|
||||
overlapped.AsyncResult = _acceptResult;
|
||||
_nativeOverlapped = new SafeNativeOverlapped(overlapped.Pack(AsyncAcceptContext.IOCallback, RequestBuffer));
|
||||
var boundHandle = _acceptResult.Server.BoundHandle;
|
||||
_nativeOverlapped = new SafeNativeOverlapped(boundHandle,
|
||||
boundHandle.AllocateNativeOverlapped(AsyncAcceptContext.IOCallback, _acceptResult, RequestBuffer));
|
||||
return (UnsafeNclNativeMethods.HttpApi.HTTP_REQUEST*)Marshal.UnsafeAddrOfPinnedArrayElement(RequestBuffer, 0);
|
||||
}
|
||||
return RequestBlob;
|
||||
|
|
|
@ -43,6 +43,11 @@ namespace Microsoft.Net.Http.Server
|
|||
_requestContext = httpContext;
|
||||
}
|
||||
|
||||
internal RequestContext RequestContext
|
||||
{
|
||||
get { return _requestContext; }
|
||||
}
|
||||
|
||||
public override bool CanSeek
|
||||
{
|
||||
get
|
||||
|
|
|
@ -64,9 +64,9 @@ namespace Microsoft.Net.Http.Server
|
|||
: this(requestStream, userState, callback)
|
||||
{
|
||||
_dataAlreadyRead = dataAlreadyRead;
|
||||
Overlapped overlapped = new Overlapped();
|
||||
overlapped.AsyncResult = this;
|
||||
_overlapped = new SafeNativeOverlapped(overlapped.Pack(IOCallback, buffer));
|
||||
var boundHandle = requestStream.RequestContext.Server.BoundHandle;
|
||||
_overlapped = new SafeNativeOverlapped(boundHandle,
|
||||
boundHandle.AllocateNativeOverlapped(IOCallback, this, buffer));
|
||||
_pinnedBuffer = (Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset));
|
||||
_cancellationRegistration = cancellationRegistration;
|
||||
}
|
||||
|
@ -126,9 +126,7 @@ namespace Microsoft.Net.Http.Server
|
|||
|
||||
private static unsafe void Callback(uint errorCode, uint numBytes, NativeOverlapped* nativeOverlapped)
|
||||
{
|
||||
Overlapped callbackOverlapped = Overlapped.Unpack(nativeOverlapped);
|
||||
RequestStreamAsyncResult asyncResult = callbackOverlapped.AsyncResult as RequestStreamAsyncResult;
|
||||
|
||||
var asyncResult = (RequestStreamAsyncResult)ThreadPoolBoundHandle.GetNativeOverlappedState(nativeOverlapped);
|
||||
IOCompleted(asyncResult, errorCode, numBytes);
|
||||
}
|
||||
|
||||
|
|
|
@ -47,6 +47,11 @@ namespace Microsoft.Net.Http.Server
|
|||
_requestContext = requestContext;
|
||||
}
|
||||
|
||||
internal RequestContext RequestContext
|
||||
{
|
||||
get { return _requestContext; }
|
||||
}
|
||||
|
||||
public override bool CanSeek
|
||||
{
|
||||
get
|
||||
|
|
|
@ -65,13 +65,13 @@ namespace Microsoft.Net.Http.Server
|
|||
{
|
||||
_sentHeaders = sentHeaders;
|
||||
_cancellationRegistration = cancellationRegistration;
|
||||
Overlapped overlapped = new Overlapped();
|
||||
overlapped.AsyncResult = this;
|
||||
var boundHandle = _responseStream.RequestContext.Server.BoundHandle;
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
_dataChunks = null;
|
||||
_overlapped = new SafeNativeOverlapped(overlapped.Pack(IOCallback, null));
|
||||
_overlapped = new SafeNativeOverlapped(boundHandle,
|
||||
boundHandle.AllocateNativeOverlapped(IOCallback, this, null));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -114,7 +114,8 @@ namespace Microsoft.Net.Http.Server
|
|||
}
|
||||
|
||||
// This call will pin needed memory
|
||||
_overlapped = new SafeNativeOverlapped(overlapped.Pack(IOCallback, objectsToPin));
|
||||
_overlapped = new SafeNativeOverlapped(boundHandle,
|
||||
boundHandle.AllocateNativeOverlapped(IOCallback, this, objectsToPin));
|
||||
|
||||
if (chunked)
|
||||
{
|
||||
|
@ -136,8 +137,7 @@ namespace Microsoft.Net.Http.Server
|
|||
{
|
||||
_sentHeaders = sentHeaders;
|
||||
_cancellationRegistration = cancellationRegistration;
|
||||
Overlapped overlapped = new Overlapped();
|
||||
overlapped.AsyncResult = this;
|
||||
var boundHandle = ResponseStream.RequestContext.Server.BoundHandle;
|
||||
|
||||
int bufferSize = 1024 * 64; // TODO: Validate buffer size choice.
|
||||
#if DNXCORE50
|
||||
|
@ -162,7 +162,8 @@ namespace Microsoft.Net.Http.Server
|
|||
if (size == 0 || (!size.HasValue && _fileStream.Length == 0))
|
||||
{
|
||||
_dataChunks = null;
|
||||
_overlapped = new SafeNativeOverlapped(overlapped.Pack(IOCallback, null));
|
||||
_overlapped = new SafeNativeOverlapped(boundHandle,
|
||||
boundHandle.AllocateNativeOverlapped(IOCallback, this, null));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -206,7 +207,8 @@ namespace Microsoft.Net.Http.Server
|
|||
}
|
||||
|
||||
// This call will pin needed memory
|
||||
_overlapped = new SafeNativeOverlapped(overlapped.Pack(IOCallback, objectsToPin));
|
||||
_overlapped = new SafeNativeOverlapped(boundHandle,
|
||||
boundHandle.AllocateNativeOverlapped(IOCallback, this, objectsToPin));
|
||||
|
||||
if (chunked)
|
||||
{
|
||||
|
@ -318,9 +320,7 @@ namespace Microsoft.Net.Http.Server
|
|||
|
||||
private static unsafe void Callback(uint errorCode, uint numBytes, NativeOverlapped* nativeOverlapped)
|
||||
{
|
||||
Overlapped callbackOverlapped = Overlapped.Unpack(nativeOverlapped);
|
||||
ResponseStreamAsyncResult asyncResult = callbackOverlapped.AsyncResult as ResponseStreamAsyncResult;
|
||||
|
||||
var asyncResult = (ResponseStreamAsyncResult)ThreadPoolBoundHandle.GetNativeOverlappedState(nativeOverlapped);
|
||||
IOCompleted(asyncResult, errorCode, numBytes);
|
||||
}
|
||||
|
||||
|
|
|
@ -74,6 +74,7 @@ namespace Microsoft.Net.Http.Server
|
|||
private ILogger _logger;
|
||||
|
||||
private SafeHandle _requestQueueHandle;
|
||||
private ThreadPoolBoundHandle _boundHandle;
|
||||
private volatile State _state; // m_State is set only within lock blocks, but often read outside locks.
|
||||
|
||||
private bool _ignoreWriteExceptions;
|
||||
|
@ -141,6 +142,11 @@ namespace Microsoft.Net.Http.Server
|
|||
}
|
||||
}
|
||||
|
||||
internal ThreadPoolBoundHandle BoundHandle
|
||||
{
|
||||
get { return _boundHandle; }
|
||||
}
|
||||
|
||||
internal ulong UrlGroupId
|
||||
{
|
||||
get { return _urlGroupId; }
|
||||
|
@ -523,7 +529,7 @@ namespace Microsoft.Net.Http.Server
|
|||
}
|
||||
|
||||
_requestQueueHandle = requestQueueHandle;
|
||||
ThreadPool.BindHandle(_requestQueueHandle);
|
||||
_boundHandle = ThreadPoolBoundHandle.BindHandle(_requestQueueHandle);
|
||||
}
|
||||
|
||||
private unsafe void CloseRequestQueueHandle()
|
||||
|
@ -532,6 +538,10 @@ namespace Microsoft.Net.Http.Server
|
|||
{
|
||||
_requestQueueHandle.Dispose();
|
||||
}
|
||||
if (_boundHandle != null)
|
||||
{
|
||||
_boundHandle.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -667,11 +677,10 @@ namespace Microsoft.Net.Http.Server
|
|||
// Debug.WriteLine("Server: Registering connection for disconnect for connection ID: " + connectionId);
|
||||
|
||||
// Create a nativeOverlapped callback so we can register for disconnect callback
|
||||
var overlapped = new Overlapped();
|
||||
var cts = new CancellationTokenSource();
|
||||
|
||||
SafeNativeOverlapped nativeOverlapped = null;
|
||||
nativeOverlapped = new SafeNativeOverlapped(overlapped.UnsafePack(
|
||||
nativeOverlapped = new SafeNativeOverlapped(_boundHandle, _boundHandle.AllocateNativeOverlapped(
|
||||
(errorCode, numBytes, overlappedPtr) =>
|
||||
{
|
||||
// Debug.WriteLine("Server: http.sys disconnect callback fired for connection ID: " + connectionId);
|
||||
|
@ -693,7 +702,7 @@ namespace Microsoft.Net.Http.Server
|
|||
|
||||
cts.Dispose();
|
||||
},
|
||||
null));
|
||||
null, null));
|
||||
|
||||
uint statusCode;
|
||||
try
|
||||
|
|
|
@ -1,97 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
|
||||
namespace Microsoft.Net.WebSockets
|
||||
{
|
||||
internal class SafeNativeOverlapped : SafeHandle
|
||||
{
|
||||
internal static readonly SafeNativeOverlapped Zero = new SafeNativeOverlapped();
|
||||
|
||||
internal SafeNativeOverlapped()
|
||||
: this(IntPtr.Zero)
|
||||
{
|
||||
}
|
||||
|
||||
internal unsafe SafeNativeOverlapped(NativeOverlapped* handle)
|
||||
: this((IntPtr)handle)
|
||||
{
|
||||
}
|
||||
|
||||
internal SafeNativeOverlapped(IntPtr handle)
|
||||
: base(IntPtr.Zero, true)
|
||||
{
|
||||
SetHandle(handle);
|
||||
}
|
||||
|
||||
public override bool IsInvalid
|
||||
{
|
||||
get { return handle == IntPtr.Zero; }
|
||||
}
|
||||
|
||||
public void ReinitializeNativeOverlapped()
|
||||
{
|
||||
IntPtr handleSnapshot = handle;
|
||||
|
||||
if (handleSnapshot != IntPtr.Zero)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
((NativeOverlapped*)handleSnapshot)->InternalHigh = IntPtr.Zero;
|
||||
((NativeOverlapped*)handleSnapshot)->InternalLow = IntPtr.Zero;
|
||||
((NativeOverlapped*)handleSnapshot)->EventHandle = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool ReleaseHandle()
|
||||
{
|
||||
IntPtr oldHandle = Interlocked.Exchange(ref handle, IntPtr.Zero);
|
||||
// Do not call free durring AppDomain shutdown, there may be an outstanding operation.
|
||||
// Overlapped will take care calling free when the native callback completes.
|
||||
if (oldHandle != IntPtr.Zero && !HasShutdownStarted)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
Overlapped.Free((NativeOverlapped*)oldHandle);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static bool HasShutdownStarted
|
||||
{
|
||||
get
|
||||
{
|
||||
return Environment.HasShutdownStarted
|
||||
#if !DNXCORE50
|
||||
|| AppDomain.CurrentDomain.IsFinalizingForUnload()
|
||||
#endif
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,7 +20,6 @@
|
|||
"System.Security.Cryptography.Hashing.Algorithms": "4.0.0-beta-*",
|
||||
"System.Text.Encoding.Extensions": "4.0.10-beta-*",
|
||||
"System.Threading": "4.0.10-beta-*",
|
||||
"System.Threading.Overlapped": "4.0.0-beta-*",
|
||||
"System.Threading.Tasks": "4.0.10-beta-*",
|
||||
"System.Threading.Timer": "4.0.0-beta-*",
|
||||
"System.Threading.ThreadPool": "4.0.10-beta-*"
|
||||
|
|
Загрузка…
Ссылка в новой задаче