internal ListenerClientCertAsyncResult(ThreadPoolBoundHandle boundHandle, object asyncObject, object userState, AsyncCallback callback, uint size) : base(asyncObject, userState, callback) { // we will use this overlapped structure to issue async IO to ul // the event handle will be put in by the BeginHttpApi2.ERROR_SUCCESS() method _boundHandle = boundHandle; Reset(size); }
private static unsafe void OnNativeIOCompleted(IntPtr instance, IntPtr context, IntPtr overlappedPtr, uint ioResult, UIntPtr numberOfBytesTransferred, IntPtr ioPtr) { Win32ThreadPoolNativeOverlapped *overlapped = (Win32ThreadPoolNativeOverlapped *)overlappedPtr; ThreadPoolBoundHandle boundHandle = overlapped->Data._boundHandle; if (boundHandle == null) { throw new InvalidOperationException(SR.Argument_NativeOverlappedAlreadyFree); } boundHandle.Release(); Win32ThreadPoolNativeOverlapped.CompleteWithCallback(ioResult, (uint)numberOfBytesTransferred, overlapped); }
private Interop.HttpApi.HTTP_REQUEST* Allocate(ThreadPoolBoundHandle boundHandle, uint size) { uint newSize = size != 0 ? size : RequestBuffer == null ? 4096 : Size; if (_nativeOverlapped != null && newSize != RequestBuffer.Length) { NativeOverlapped* nativeOverlapped = _nativeOverlapped; _nativeOverlapped = null; _boundHandle.FreeNativeOverlapped(nativeOverlapped); } if (_nativeOverlapped == null) { SetBuffer(checked((int)newSize)); _boundHandle = boundHandle; _nativeOverlapped = boundHandle.AllocateNativeOverlapped(ListenerAsyncResult.IOCallback, state: _result, pinData: RequestBuffer); return (Interop.HttpApi.HTTP_REQUEST*)Marshal.UnsafeAddrOfPinnedArrayElement(RequestBuffer, 0); } return RequestBlob; }
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); }
// Binds the Socket Win32 Handle to the ThreadPool's CompletionPort. public ThreadPoolBoundHandle GetOrAllocateThreadPoolBoundHandle() { if (_released) { // Keep the exception message pointing at the external type. throw new ObjectDisposedException(typeof(Socket).FullName); } // Check to see if the socket native _handle is already // bound to the ThreadPool's completion port. if (_iocpBoundHandle == null) { lock (_iocpBindingLock) { if (_iocpBoundHandle == null) { // Bind the socket native _handle to the ThreadPool. if (GlobalLog.IsEnabled) { GlobalLog.Print("SafeCloseSocket#" + LoggingHash.HashString(this) + "::BindToCompletionPort() calling ThreadPool.BindHandle()"); } try { // The handle (this) may have been already released: // E.g.: The socket has been disposed in the main thread. A completion callback may // attempt starting another operation. _iocpBoundHandle = ThreadPoolBoundHandle.BindHandle(this); } catch (Exception exception) { if (ExceptionCheck.IsFatal(exception)) throw; CloseAsIs(); throw; } } } } return _iocpBoundHandle; }
// Will be called from the base class upon InvokeCallback() protected override void Cleanup() { if (_pOverlapped != null) { _memoryBlob = null; _boundHandle.FreeNativeOverlapped(_pOverlapped); _pOverlapped = null; _boundHandle = null; } GC.SuppressFinalize(this); base.Cleanup(); }
private static unsafe Win32ThreadPoolNativeOverlapped.OverlappedData GetOverlappedData(Win32ThreadPoolNativeOverlapped* overlapped, ThreadPoolBoundHandle expectedBoundHandle) { Win32ThreadPoolNativeOverlapped.OverlappedData data = overlapped->Data; if (data._boundHandle == null) throw new ArgumentException(SR.Argument_NativeOverlappedAlreadyFree, "overlapped"); if (expectedBoundHandle != null && data._boundHandle != expectedBoundHandle) throw new ArgumentException(SR.Argument_NativeOverlappedWrongBoundHandle, "overlapped"); return data; }
private static unsafe ThreadPoolBoundHandleOverlapped GetOverlappedWrapper(NativeOverlapped* overlapped, ThreadPoolBoundHandle expectedBoundHandle) { ThreadPoolBoundHandleOverlapped wrapper; try { wrapper = (ThreadPoolBoundHandleOverlapped)Overlapped.Unpack(overlapped); } catch (NullReferenceException ex) { throw new ArgumentException(SR.Argument_NativeOverlappedAlreadyFree, "overlapped", ex); } return wrapper; }
internal AsyncRequestContext(ThreadPoolBoundHandle boundHandle, ListenerAsyncResult result) { _result = result; BaseConstruction(Allocate(boundHandle, 0)); }
/// <summary>Initializes the handle to be used asynchronously.</summary> /// <param name="handle">The handle.</param> private void InitializeAsyncHandle(SafePipeHandle handle) { // If the handle is of async type, bind the handle to the ThreadPool so that we can use // the async operations (it's needed so that our native callbacks get called). _threadPoolBinding = ThreadPoolBoundHandle.BindHandle(handle); }
private unsafe void InitializeOverlapped(ThreadPoolBoundHandle boundHandle) { _boundHandle = boundHandle; _ptrNativeOverlapped = boundHandle.AllocateNativeOverlapped(CompletionPortCallback, null, null); }
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); }
private unsafe static ThreadPoolBoundHandleOverlapped GetOverlappedWrapper(NativeOverlapped *overlapped, ThreadPoolBoundHandle expectedBoundHandle) { ThreadPoolBoundHandleOverlapped result; try { result = (ThreadPoolBoundHandleOverlapped)Overlapped.Unpack(overlapped); } catch (NullReferenceException innerException) { throw new ArgumentException(Environment.GetResourceString("Argument_NativeOverlappedAlreadyFree"), "overlapped", innerException); } return(result); }
internal void Reset(ThreadPoolBoundHandle boundHandle, ulong requestId, uint size) { SetBlob(Allocate(boundHandle, size)); RequestBlob->RequestId = requestId; }
internal AsyncReadState(int session, byte[] buffer, SafeFileHandle handle, ThreadPoolBoundHandle binding) { Debug.Assert(buffer != null); Debug.Assert(handle != null); Debug.Assert(binding != null); Session = session; Buffer = buffer; DirectoryHandle = handle; ThreadPoolBinding = binding; }
// Method called to prepare for a native async http.sys call. // This method performs the tasks common to all http.sys operations. internal void StartOperationCommon(WebSocketHttpListenerDuplexStream currentStream, ThreadPoolBoundHandle boundHandle) { // Change status to "in-use". if (Interlocked.CompareExchange(ref _operating, InProgress, Free) != Free) { // If it was already "in-use" check if Dispose was called. if (_disposeCalled) { // Dispose was called - throw ObjectDisposed. throw new ObjectDisposedException(GetType().FullName); } Debug.Assert(false, "Only one outstanding async operation is allowed per HttpListenerAsyncEventArgs instance."); // Only one at a time. throw new InvalidOperationException(); } // HttpSendResponseEntityBody can return ERROR_INVALID_PARAMETER if the InternalHigh field of the overlapped // is not IntPtr.Zero, so we have to reset this field because we are reusing the Overlapped. // When using the IAsyncResult based approach of HttpListenerResponseStream the Overlapped is reinitialized // for each operation by the CLR when returned from the OverlappedDataCache. InitializeOverlapped(boundHandle); _exception = null; _bytesTransferred = 0; }
private static unsafe ThreadPoolBoundHandleOverlapped GetOverlappedWrapper(NativeOverlapped *overlapped, ThreadPoolBoundHandle expectedBoundHandle) { ThreadPoolBoundHandleOverlapped wrapper; try { wrapper = (ThreadPoolBoundHandleOverlapped)Overlapped.Unpack(overlapped); } catch (NullReferenceException ex) { throw new ArgumentException(SR.Argument_NativeOverlappedAlreadyFree, "overlapped", ex); } return(wrapper); }
private static unsafe ThreadPoolBoundHandleOverlapped GetOverlappedWrapper(NativeOverlapped *overlapped, ThreadPoolBoundHandle expectedBoundHandle) { ThreadPoolBoundHandleOverlapped wrapper; try { wrapper = (ThreadPoolBoundHandleOverlapped)Overlapped.Unpack(overlapped); } catch (NullReferenceException ex) { throw new ArgumentException(Environment.GetResourceString("Argument_NativeOverlappedAlreadyFree"), nameof(overlapped), ex); } return(wrapper); }
internal HttpRequestStreamAsyncResult(ThreadPoolBoundHandle boundHandle, object asyncObject, object userState, AsyncCallback callback, byte[] buffer, int offset, uint size, uint dataAlreadyRead) : base(asyncObject, userState, callback) { _dataAlreadyRead = dataAlreadyRead; _boundHandle = boundHandle; _pOverlapped = boundHandle.AllocateNativeOverlapped(s_IOCallback, state: this, pinData: buffer); _pPinnedBuffer = (void*)(Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset)); }
private static unsafe Win32ThreadPoolNativeOverlapped.OverlappedData GetOverlappedData(Win32ThreadPoolNativeOverlapped *overlapped, ThreadPoolBoundHandle expectedBoundHandle) { Win32ThreadPoolNativeOverlapped.OverlappedData data = overlapped->Data; if (data._boundHandle == null) { throw new ArgumentException(SR.Argument_NativeOverlappedAlreadyFree, nameof(overlapped)); } if (expectedBoundHandle != null && data._boundHandle != expectedBoundHandle) { throw new ArgumentException(SR.Argument_NativeOverlappedWrongBoundHandle, nameof(overlapped)); } return(data); }
internal HttpResponseStreamAsyncResult(object asyncObject, object userState, AsyncCallback callback, byte[] buffer, int offset, int size, bool chunked, bool sentHeaders, ThreadPoolBoundHandle boundHandle) : base(asyncObject, userState, callback) { _boundHandle = boundHandle; _sentHeaders = sentHeaders; if (size == 0) { _dataChunks = null; _pOverlapped = boundHandle.AllocateNativeOverlapped(s_IOCallback, state: this, pinData: null); } else { _dataChunks = new Interop.HttpApi.HTTP_DATA_CHUNK[chunked ? 3 : 1]; if (NetEventSource.IsEnabled) NetEventSource.Info(this, "m_pOverlapped:0x" + ((IntPtr)_pOverlapped).ToString("x8")); object[] objectsToPin = new object[1 + _dataChunks.Length]; objectsToPin[_dataChunks.Length] = _dataChunks; int chunkHeaderOffset = 0; byte[] chunkHeaderBuffer = null; if (chunked) { chunkHeaderBuffer = GetChunkHeader(size, out chunkHeaderOffset); _dataChunks[0] = new Interop.HttpApi.HTTP_DATA_CHUNK(); _dataChunks[0].DataChunkType = Interop.HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory; _dataChunks[0].BufferLength = (uint)(chunkHeaderBuffer.Length - chunkHeaderOffset); objectsToPin[0] = chunkHeaderBuffer; _dataChunks[1] = new Interop.HttpApi.HTTP_DATA_CHUNK(); _dataChunks[1].DataChunkType = Interop.HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory; _dataChunks[1].BufferLength = (uint)size; objectsToPin[1] = buffer; _dataChunks[2] = new Interop.HttpApi.HTTP_DATA_CHUNK(); _dataChunks[2].DataChunkType = Interop.HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory; _dataChunks[2].BufferLength = (uint)s_CRLFArray.Length; objectsToPin[2] = s_CRLFArray; } else { _dataChunks[0] = new Interop.HttpApi.HTTP_DATA_CHUNK(); _dataChunks[0].DataChunkType = Interop.HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory; _dataChunks[0].BufferLength = (uint)size; objectsToPin[0] = buffer; } // This call will pin needed memory _pOverlapped = boundHandle.AllocateNativeOverlapped(s_IOCallback, state: this, pinData: objectsToPin); if (chunked) { _dataChunks[0].pBuffer = (byte*)(Marshal.UnsafeAddrOfPinnedArrayElement(chunkHeaderBuffer, chunkHeaderOffset)); _dataChunks[1].pBuffer = (byte*)(Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset)); _dataChunks[2].pBuffer = (byte*)(Marshal.UnsafeAddrOfPinnedArrayElement(s_CRLFArray, 0)); } else { _dataChunks[0].pBuffer = (byte*)(Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset)); } } }