Merge branch 'release' into dev
This commit is contained in:
commit
0acb8f3ed4
|
|
@ -60,7 +60,7 @@ namespace Microsoft.Net.Http.Server
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private WebListener Server
|
internal WebListener Server
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
|
@ -152,9 +152,7 @@ namespace Microsoft.Net.Http.Server
|
||||||
private static unsafe void IOWaitCallback(uint errorCode, uint numBytes, NativeOverlapped* nativeOverlapped)
|
private static unsafe void IOWaitCallback(uint errorCode, uint numBytes, NativeOverlapped* nativeOverlapped)
|
||||||
{
|
{
|
||||||
// take the ListenerAsyncResult object from the state
|
// take the ListenerAsyncResult object from the state
|
||||||
Overlapped callbackOverlapped = Overlapped.Unpack(nativeOverlapped);
|
var asyncResult = (AsyncAcceptContext)ThreadPoolBoundHandle.GetNativeOverlappedState(nativeOverlapped);
|
||||||
AsyncAcceptContext asyncResult = (AsyncAcceptContext)callbackOverlapped.AsyncResult;
|
|
||||||
|
|
||||||
IOCompleted(asyncResult, errorCode, numBytes);
|
IOCompleted(asyncResult, errorCode, numBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,21 +30,18 @@ namespace Microsoft.Net.Http.Server
|
||||||
internal class SafeNativeOverlapped : SafeHandle
|
internal class SafeNativeOverlapped : SafeHandle
|
||||||
{
|
{
|
||||||
internal static readonly SafeNativeOverlapped Zero = new SafeNativeOverlapped();
|
internal static readonly SafeNativeOverlapped Zero = new SafeNativeOverlapped();
|
||||||
|
private ThreadPoolBoundHandle _boundHandle;
|
||||||
|
|
||||||
internal SafeNativeOverlapped()
|
internal SafeNativeOverlapped()
|
||||||
: this(IntPtr.Zero)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
internal unsafe SafeNativeOverlapped(NativeOverlapped* handle)
|
|
||||||
: this((IntPtr)handle)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
internal SafeNativeOverlapped(IntPtr handle)
|
|
||||||
: base(IntPtr.Zero, true)
|
: 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
|
public override bool IsInvalid
|
||||||
|
|
@ -76,7 +73,7 @@ namespace Microsoft.Net.Http.Server
|
||||||
{
|
{
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
Overlapped.Free((NativeOverlapped*)oldHandle);
|
_boundHandle.FreeNativeOverlapped((NativeOverlapped*)oldHandle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
_backingBuffer = new byte[checked((int)size)];
|
_backingBuffer = new byte[checked((int)size)];
|
||||||
Overlapped overlapped = new Overlapped();
|
var boundHandle = RequestContext.Server.BoundHandle;
|
||||||
overlapped.AsyncResult = this;
|
_overlapped = new SafeNativeOverlapped(boundHandle,
|
||||||
_overlapped = new SafeNativeOverlapped(overlapped.Pack(IOCallback, _backingBuffer));
|
boundHandle.AllocateNativeOverlapped(IOCallback, this, _backingBuffer));
|
||||||
_memoryBlob = (UnsafeNclNativeMethods.HttpApi.HTTP_SSL_CLIENT_CERT_INFO*)Marshal.UnsafeAddrOfPinnedArrayElement(_backingBuffer, 0);
|
_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)
|
private static unsafe void WaitCallback(uint errorCode, uint numBytes, NativeOverlapped* nativeOverlapped)
|
||||||
{
|
{
|
||||||
Overlapped callbackOverlapped = Overlapped.Unpack(nativeOverlapped);
|
var asyncResult = (ClientCertLoader)ThreadPoolBoundHandle.GetNativeOverlappedState(nativeOverlapped);
|
||||||
ClientCertLoader asyncResult = (ClientCertLoader)callbackOverlapped.AsyncResult;
|
|
||||||
|
|
||||||
IOCompleted(asyncResult, errorCode, numBytes);
|
IOCompleted(asyncResult, errorCode, numBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -161,7 +161,8 @@ namespace Microsoft.Net.Http.Server
|
||||||
private UnsafeNclNativeMethods.HttpApi.HTTP_REQUEST* Allocate(uint size)
|
private UnsafeNclNativeMethods.HttpApi.HTTP_REQUEST* Allocate(uint size)
|
||||||
{
|
{
|
||||||
uint newSize = size != 0 ? size : RequestBuffer == null ? DefaultBufferSize : 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;
|
SafeNativeOverlapped nativeOverlapped = _nativeOverlapped;
|
||||||
_nativeOverlapped = null;
|
_nativeOverlapped = null;
|
||||||
|
|
@ -170,9 +171,9 @@ namespace Microsoft.Net.Http.Server
|
||||||
if (_nativeOverlapped == null)
|
if (_nativeOverlapped == null)
|
||||||
{
|
{
|
||||||
SetBuffer(checked((int)newSize));
|
SetBuffer(checked((int)newSize));
|
||||||
Overlapped overlapped = new Overlapped();
|
var boundHandle = _acceptResult.Server.BoundHandle;
|
||||||
overlapped.AsyncResult = _acceptResult;
|
_nativeOverlapped = new SafeNativeOverlapped(boundHandle,
|
||||||
_nativeOverlapped = new SafeNativeOverlapped(overlapped.Pack(AsyncAcceptContext.IOCallback, RequestBuffer));
|
boundHandle.AllocateNativeOverlapped(AsyncAcceptContext.IOCallback, _acceptResult, RequestBuffer));
|
||||||
return (UnsafeNclNativeMethods.HttpApi.HTTP_REQUEST*)Marshal.UnsafeAddrOfPinnedArrayElement(RequestBuffer, 0);
|
return (UnsafeNclNativeMethods.HttpApi.HTTP_REQUEST*)Marshal.UnsafeAddrOfPinnedArrayElement(RequestBuffer, 0);
|
||||||
}
|
}
|
||||||
return RequestBlob;
|
return RequestBlob;
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,11 @@ namespace Microsoft.Net.Http.Server
|
||||||
_requestContext = httpContext;
|
_requestContext = httpContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal RequestContext RequestContext
|
||||||
|
{
|
||||||
|
get { return _requestContext; }
|
||||||
|
}
|
||||||
|
|
||||||
public override bool CanSeek
|
public override bool CanSeek
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|
|
||||||
|
|
@ -64,9 +64,9 @@ namespace Microsoft.Net.Http.Server
|
||||||
: this(requestStream, userState, callback)
|
: this(requestStream, userState, callback)
|
||||||
{
|
{
|
||||||
_dataAlreadyRead = dataAlreadyRead;
|
_dataAlreadyRead = dataAlreadyRead;
|
||||||
Overlapped overlapped = new Overlapped();
|
var boundHandle = requestStream.RequestContext.Server.BoundHandle;
|
||||||
overlapped.AsyncResult = this;
|
_overlapped = new SafeNativeOverlapped(boundHandle,
|
||||||
_overlapped = new SafeNativeOverlapped(overlapped.Pack(IOCallback, buffer));
|
boundHandle.AllocateNativeOverlapped(IOCallback, this, buffer));
|
||||||
_pinnedBuffer = (Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset));
|
_pinnedBuffer = (Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset));
|
||||||
_cancellationRegistration = cancellationRegistration;
|
_cancellationRegistration = cancellationRegistration;
|
||||||
}
|
}
|
||||||
|
|
@ -126,9 +126,7 @@ namespace Microsoft.Net.Http.Server
|
||||||
|
|
||||||
private static unsafe void Callback(uint errorCode, uint numBytes, NativeOverlapped* nativeOverlapped)
|
private static unsafe void Callback(uint errorCode, uint numBytes, NativeOverlapped* nativeOverlapped)
|
||||||
{
|
{
|
||||||
Overlapped callbackOverlapped = Overlapped.Unpack(nativeOverlapped);
|
var asyncResult = (RequestStreamAsyncResult)ThreadPoolBoundHandle.GetNativeOverlappedState(nativeOverlapped);
|
||||||
RequestStreamAsyncResult asyncResult = callbackOverlapped.AsyncResult as RequestStreamAsyncResult;
|
|
||||||
|
|
||||||
IOCompleted(asyncResult, errorCode, numBytes);
|
IOCompleted(asyncResult, errorCode, numBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,11 @@ namespace Microsoft.Net.Http.Server
|
||||||
_requestContext = requestContext;
|
_requestContext = requestContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal RequestContext RequestContext
|
||||||
|
{
|
||||||
|
get { return _requestContext; }
|
||||||
|
}
|
||||||
|
|
||||||
public override bool CanSeek
|
public override bool CanSeek
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|
|
||||||
|
|
@ -65,13 +65,13 @@ namespace Microsoft.Net.Http.Server
|
||||||
{
|
{
|
||||||
_sentHeaders = sentHeaders;
|
_sentHeaders = sentHeaders;
|
||||||
_cancellationRegistration = cancellationRegistration;
|
_cancellationRegistration = cancellationRegistration;
|
||||||
Overlapped overlapped = new Overlapped();
|
var boundHandle = _responseStream.RequestContext.Server.BoundHandle;
|
||||||
overlapped.AsyncResult = this;
|
|
||||||
|
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
{
|
{
|
||||||
_dataChunks = null;
|
_dataChunks = null;
|
||||||
_overlapped = new SafeNativeOverlapped(overlapped.Pack(IOCallback, null));
|
_overlapped = new SafeNativeOverlapped(boundHandle,
|
||||||
|
boundHandle.AllocateNativeOverlapped(IOCallback, this, null));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -114,7 +114,8 @@ namespace Microsoft.Net.Http.Server
|
||||||
}
|
}
|
||||||
|
|
||||||
// This call will pin needed memory
|
// This call will pin needed memory
|
||||||
_overlapped = new SafeNativeOverlapped(overlapped.Pack(IOCallback, objectsToPin));
|
_overlapped = new SafeNativeOverlapped(boundHandle,
|
||||||
|
boundHandle.AllocateNativeOverlapped(IOCallback, this, objectsToPin));
|
||||||
|
|
||||||
if (chunked)
|
if (chunked)
|
||||||
{
|
{
|
||||||
|
|
@ -136,8 +137,7 @@ namespace Microsoft.Net.Http.Server
|
||||||
{
|
{
|
||||||
_sentHeaders = sentHeaders;
|
_sentHeaders = sentHeaders;
|
||||||
_cancellationRegistration = cancellationRegistration;
|
_cancellationRegistration = cancellationRegistration;
|
||||||
Overlapped overlapped = new Overlapped();
|
var boundHandle = ResponseStream.RequestContext.Server.BoundHandle;
|
||||||
overlapped.AsyncResult = this;
|
|
||||||
|
|
||||||
int bufferSize = 1024 * 64; // TODO: Validate buffer size choice.
|
int bufferSize = 1024 * 64; // TODO: Validate buffer size choice.
|
||||||
#if DNXCORE50
|
#if DNXCORE50
|
||||||
|
|
@ -162,7 +162,8 @@ namespace Microsoft.Net.Http.Server
|
||||||
if (size == 0 || (!size.HasValue && _fileStream.Length == 0))
|
if (size == 0 || (!size.HasValue && _fileStream.Length == 0))
|
||||||
{
|
{
|
||||||
_dataChunks = null;
|
_dataChunks = null;
|
||||||
_overlapped = new SafeNativeOverlapped(overlapped.Pack(IOCallback, null));
|
_overlapped = new SafeNativeOverlapped(boundHandle,
|
||||||
|
boundHandle.AllocateNativeOverlapped(IOCallback, this, null));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -206,7 +207,8 @@ namespace Microsoft.Net.Http.Server
|
||||||
}
|
}
|
||||||
|
|
||||||
// This call will pin needed memory
|
// This call will pin needed memory
|
||||||
_overlapped = new SafeNativeOverlapped(overlapped.Pack(IOCallback, objectsToPin));
|
_overlapped = new SafeNativeOverlapped(boundHandle,
|
||||||
|
boundHandle.AllocateNativeOverlapped(IOCallback, this, objectsToPin));
|
||||||
|
|
||||||
if (chunked)
|
if (chunked)
|
||||||
{
|
{
|
||||||
|
|
@ -318,9 +320,7 @@ namespace Microsoft.Net.Http.Server
|
||||||
|
|
||||||
private static unsafe void Callback(uint errorCode, uint numBytes, NativeOverlapped* nativeOverlapped)
|
private static unsafe void Callback(uint errorCode, uint numBytes, NativeOverlapped* nativeOverlapped)
|
||||||
{
|
{
|
||||||
Overlapped callbackOverlapped = Overlapped.Unpack(nativeOverlapped);
|
var asyncResult = (ResponseStreamAsyncResult)ThreadPoolBoundHandle.GetNativeOverlappedState(nativeOverlapped);
|
||||||
ResponseStreamAsyncResult asyncResult = callbackOverlapped.AsyncResult as ResponseStreamAsyncResult;
|
|
||||||
|
|
||||||
IOCompleted(asyncResult, errorCode, numBytes);
|
IOCompleted(asyncResult, errorCode, numBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,7 @@ namespace Microsoft.Net.Http.Server
|
||||||
private ILogger _logger;
|
private ILogger _logger;
|
||||||
|
|
||||||
private SafeHandle _requestQueueHandle;
|
private SafeHandle _requestQueueHandle;
|
||||||
|
private ThreadPoolBoundHandle _boundHandle;
|
||||||
private volatile State _state; // m_State is set only within lock blocks, but often read outside locks.
|
private volatile State _state; // m_State is set only within lock blocks, but often read outside locks.
|
||||||
|
|
||||||
private bool _ignoreWriteExceptions;
|
private bool _ignoreWriteExceptions;
|
||||||
|
|
@ -141,6 +142,11 @@ namespace Microsoft.Net.Http.Server
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal ThreadPoolBoundHandle BoundHandle
|
||||||
|
{
|
||||||
|
get { return _boundHandle; }
|
||||||
|
}
|
||||||
|
|
||||||
internal ulong UrlGroupId
|
internal ulong UrlGroupId
|
||||||
{
|
{
|
||||||
get { return _urlGroupId; }
|
get { return _urlGroupId; }
|
||||||
|
|
@ -523,7 +529,7 @@ namespace Microsoft.Net.Http.Server
|
||||||
}
|
}
|
||||||
|
|
||||||
_requestQueueHandle = requestQueueHandle;
|
_requestQueueHandle = requestQueueHandle;
|
||||||
ThreadPool.BindHandle(_requestQueueHandle);
|
_boundHandle = ThreadPoolBoundHandle.BindHandle(_requestQueueHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe void CloseRequestQueueHandle()
|
private unsafe void CloseRequestQueueHandle()
|
||||||
|
|
@ -532,6 +538,10 @@ namespace Microsoft.Net.Http.Server
|
||||||
{
|
{
|
||||||
_requestQueueHandle.Dispose();
|
_requestQueueHandle.Dispose();
|
||||||
}
|
}
|
||||||
|
if (_boundHandle != null)
|
||||||
|
{
|
||||||
|
_boundHandle.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -667,11 +677,10 @@ namespace Microsoft.Net.Http.Server
|
||||||
// Debug.WriteLine("Server: Registering connection for disconnect for connection ID: " + connectionId);
|
// Debug.WriteLine("Server: Registering connection for disconnect for connection ID: " + connectionId);
|
||||||
|
|
||||||
// Create a nativeOverlapped callback so we can register for disconnect callback
|
// Create a nativeOverlapped callback so we can register for disconnect callback
|
||||||
var overlapped = new Overlapped();
|
|
||||||
var cts = new CancellationTokenSource();
|
var cts = new CancellationTokenSource();
|
||||||
|
|
||||||
SafeNativeOverlapped nativeOverlapped = null;
|
SafeNativeOverlapped nativeOverlapped = null;
|
||||||
nativeOverlapped = new SafeNativeOverlapped(overlapped.UnsafePack(
|
nativeOverlapped = new SafeNativeOverlapped(_boundHandle, _boundHandle.AllocateNativeOverlapped(
|
||||||
(errorCode, numBytes, overlappedPtr) =>
|
(errorCode, numBytes, overlappedPtr) =>
|
||||||
{
|
{
|
||||||
// Debug.WriteLine("Server: http.sys disconnect callback fired for connection ID: " + connectionId);
|
// Debug.WriteLine("Server: http.sys disconnect callback fired for connection ID: " + connectionId);
|
||||||
|
|
@ -693,7 +702,7 @@ namespace Microsoft.Net.Http.Server
|
||||||
|
|
||||||
cts.Dispose();
|
cts.Dispose();
|
||||||
},
|
},
|
||||||
null));
|
null, null));
|
||||||
|
|
||||||
uint statusCode;
|
uint statusCode;
|
||||||
try
|
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.Security.Cryptography.Hashing.Algorithms": "4.0.0-beta-*",
|
||||||
"System.Text.Encoding.Extensions": "4.0.10-beta-*",
|
"System.Text.Encoding.Extensions": "4.0.10-beta-*",
|
||||||
"System.Threading": "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.Tasks": "4.0.10-beta-*",
|
||||||
"System.Threading.Timer": "4.0.0-beta-*",
|
"System.Threading.Timer": "4.0.0-beta-*",
|
||||||
"System.Threading.ThreadPool": "4.0.10-beta-*"
|
"System.Threading.ThreadPool": "4.0.10-beta-*"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue