public unsafe void FreeNativeOverlapped(NativeOverlapped *overlapped) { if (overlapped == null) { throw new ArgumentNullException(nameof(overlapped)); } Win32ThreadPoolNativeOverlapped *threadPoolOverlapped = Win32ThreadPoolNativeOverlapped.FromNativeOverlapped(overlapped); Win32ThreadPoolNativeOverlapped.OverlappedData data = GetOverlappedData(threadPoolOverlapped, this); if (!data._completed) { Interop.mincore.CancelThreadpoolIo(_threadPoolHandle); Release(); } data._boundHandle = null; data._completed = false; if (data._preAllocated != null) { data._preAllocated.Release(); } else { Win32ThreadPoolNativeOverlapped.Free(threadPoolOverlapped); } }
private unsafe PreAllocatedOverlapped(IOCompletionCallback callback, object?state, object?pinData, bool flowExecutionContext) { if (callback == null) { throw new ArgumentNullException(nameof(callback)); } _overlapped = Win32ThreadPoolNativeOverlapped.Allocate(callback, state, pinData, this, flowExecutionContext); }
public unsafe PreAllocatedOverlapped(IOCompletionCallback callback, object state, object pinData) { if (callback == null) { throw new ArgumentNullException(nameof(callback)); } _overlapped = Win32ThreadPoolNativeOverlapped.Allocate(callback, state, pinData, this); }
public static unsafe object GetNativeOverlappedState(NativeOverlapped *overlapped) { if (overlapped == null) { throw new ArgumentNullException(nameof(overlapped)); } Win32ThreadPoolNativeOverlapped *threadPoolOverlapped = Win32ThreadPoolNativeOverlapped.FromNativeOverlapped(overlapped); Win32ThreadPoolNativeOverlapped.OverlappedData data = GetOverlappedData(threadPoolOverlapped, null); return(threadPoolOverlapped->Data._state); }
unsafe void IDeferredDisposable.OnFinalRelease(bool disposed) { if (_overlapped != null) { if (disposed) { Win32ThreadPoolNativeOverlapped.Free(_overlapped); } else { *Win32ThreadPoolNativeOverlapped.ToNativeOverlapped(_overlapped) = default(NativeOverlapped); } } }
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); }
public unsafe NativeOverlapped *AllocateNativeOverlapped(PreAllocatedOverlapped preAllocated) { if (preAllocated == null) { throw new ArgumentNullException(nameof(preAllocated)); } bool addedRefToThis = false; bool addedRefToPreAllocated = false; try { addedRefToThis = AddRef(); addedRefToPreAllocated = preAllocated.AddRef(); Win32ThreadPoolNativeOverlapped.OverlappedData data = preAllocated._overlapped->Data; if (data._boundHandle != null) { throw new ArgumentException(SR.Argument_PreAllocatedAlreadyAllocated, nameof(preAllocated)); } data._boundHandle = this; Interop.mincore.StartThreadpoolIo(_threadPoolHandle); return(Win32ThreadPoolNativeOverlapped.ToNativeOverlapped(preAllocated._overlapped)); } catch { if (addedRefToPreAllocated) { preAllocated.Release(); } if (addedRefToThis) { Release(); } throw; } }
public unsafe NativeOverlapped *AllocateNativeOverlapped(IOCompletionCallback callback, object state, object pinData) { if (callback == null) { throw new ArgumentNullException(nameof(callback)); } AddRef(); try { Win32ThreadPoolNativeOverlapped *overlapped = Win32ThreadPoolNativeOverlapped.Allocate(callback, state, pinData, preAllocated: null); overlapped->Data._boundHandle = this; Interop.mincore.StartThreadpoolIo(_threadPoolHandle); return(Win32ThreadPoolNativeOverlapped.ToNativeOverlapped(overlapped)); } catch { Release(); throw; } }
internal unsafe static void CompleteWithCallback(uint errorCode, uint bytesWritten, Win32ThreadPoolNativeOverlapped* overlapped) { OverlappedData data = overlapped->Data; Debug.Assert(!data._completed); data._completed = true; ContextCallback callback = s_executionContextCallback; if (callback == null) s_executionContextCallback = callback = OnExecutionContextCallback; // Get an args object from the per-thread cache. ExecutionContextCallbackArgs args = t_executionContextCallbackArgs; if (args == null) args = new ExecutionContextCallbackArgs(); t_executionContextCallbackArgs = null; args._errorCode = errorCode; args._bytesWritten = bytesWritten; args._overlapped = overlapped; args._data = data; ExecutionContext.Run(data._executionContext, callback, args); }
internal unsafe static NativeOverlapped* ToNativeOverlapped(Win32ThreadPoolNativeOverlapped* overlapped) { return (NativeOverlapped*)overlapped; }
internal unsafe static void Free(Win32ThreadPoolNativeOverlapped* overlapped) { // Reset all data. overlapped->Data.Reset(); overlapped->_overlapped = default(NativeOverlapped); // Add to the free list. while (true) { IntPtr freePtr = Volatile.Read(ref s_freeList); overlapped->_nextFree = freePtr; if (Interlocked.CompareExchange(ref s_freeList, (IntPtr)overlapped, freePtr) == freePtr) break; } }
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; }