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 void InitThreadPoolBinding() { Debug.Assert(IsAsync); // This is necessary for async IO using IO Completion ports via our // managed Threadpool API's. This (theoretically) calls the OS's // BindIoCompletionCallback method, and passes in a stub for the // LPOVERLAPPED_COMPLETION_ROUTINE. This stub looks at the Overlapped // struct for this request and gets a delegate to a managed callback // from there, which it then calls on a threadpool thread. (We allocate // our native OVERLAPPED structs 2 pointers too large and store EE state // & GC handles there, one to an IAsyncResult, the other to a delegate.) try { ThreadPoolBinding = ThreadPoolBoundHandle.BindHandle(this); } catch (ArgumentException ex) { if (OwnsHandle) { // We should close the handle so that the handle is not open until SafeFileHandle GC Dispose(); } throw new IOException(SR.IO_BindHandleFailed, ex); } }
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 unsafe void InitializeOverlapped(ThreadPoolBoundHandle boundHandle) { #if DEBUG DebugRefCountAllocNativeOverlapped(); #endif _boundHandle = boundHandle; _ptrNativeOverlapped = boundHandle.AllocateNativeOverlapped(CompletionPortCallback, null, null); }
// 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 unsafe void FreeNativeOverlapped() { // Do not call free during AppDomain shutdown, there may be an outstanding operation. // Overlapped will take care calling free when the native callback completes. IntPtr oldHandle = Interlocked.Exchange(ref handle, IntPtr.Zero); if (oldHandle != IntPtr.Zero && !Environment.HasShutdownStarted) { Debug.Assert(OperatingSystem.IsWindows()); Debug.Assert(_socketHandle != null, "_socketHandle is null."); ThreadPoolBoundHandle?boundHandle = _socketHandle.IOCPBoundHandle; Debug.Assert(boundHandle != null, "SafeNativeOverlapped::FreeNativeOverlapped - boundHandle is null"); // FreeNativeOverlapped will be called even if boundHandle was previously disposed. boundHandle?.FreeNativeOverlapped((NativeOverlapped *)oldHandle); } }
private Interop.HttpApi.HTTP_REQUEST *Allocate(ThreadPoolBoundHandle boundHandle, uint size) { uint newSize = size != 0 ? size : RequestBuffer == IntPtr.Zero ? 4096 : Size; if (_nativeOverlapped != null) { #if DEBUG DebugRefCountReleaseNativeOverlapped(); #endif NativeOverlapped *nativeOverlapped = _nativeOverlapped; _nativeOverlapped = null; _boundHandle !.FreeNativeOverlapped(nativeOverlapped); } #if DEBUG DebugRefCountAllocNativeOverlapped(); #endif SetBuffer(checked ((int)newSize)); _boundHandle = boundHandle; _nativeOverlapped = boundHandle.AllocateNativeOverlapped(ListenerAsyncResult.IOCallback, state: _result, pinData: RequestBuffer); return((Interop.HttpApi.HTTP_REQUEST *)RequestBuffer.ToPointer()); }
internal unsafe SafeNativeOverlapped(ThreadPoolBoundHandle boundHandle, NativeOverlapped *handle) : base(IntPtr.Zero, true) { SetHandle((IntPtr)handle); _boundHandle = boundHandle; }
/// <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); }
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.Log.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] = default; _dataChunks[0].DataChunkType = Interop.HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory; _dataChunks[0].BufferLength = (uint)(chunkHeaderBuffer.Length - chunkHeaderOffset); objectsToPin[0] = chunkHeaderBuffer; _dataChunks[1] = default; _dataChunks[1].DataChunkType = Interop.HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory; _dataChunks[1].BufferLength = (uint)size; objectsToPin[1] = buffer; _dataChunks[2] = default; _dataChunks[2].DataChunkType = Interop.HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory; _dataChunks[2].BufferLength = (uint)s_CRLFArray.Length; objectsToPin[2] = s_CRLFArray; } else { _dataChunks[0] = default; _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)); } } }
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, nameof(overlapped), ex); } return(wrapper); }