Beispiel #1
0
        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);
            }
        }
        public unsafe PreAllocatedOverlapped(IOCompletionCallback callback, object state, object pinData)
        {
            if (callback == null)
                throw new ArgumentNullException("callback");

            _overlapped = Win32ThreadPoolNativeOverlapped.Allocate(callback, state, pinData, this);
        }
Beispiel #3
0
        public unsafe PreAllocatedOverlapped(IOCompletionCallback callback, object state, object pinData)
        {
            if (callback == null)
            {
                throw new ArgumentNullException(nameof(callback));
            }

            _overlapped = Win32ThreadPoolNativeOverlapped.Allocate(callback, state, pinData, this);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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);
        }
        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);
        }
        internal static unsafe Win32ThreadPoolNativeOverlapped *Allocate(IOCompletionCallback callback, object state, object pinData, PreAllocatedOverlapped preAllocated, bool flowExecutionControl)
        {
            Win32ThreadPoolNativeOverlapped *overlapped = AllocateNew();

            try
            {
                overlapped->SetData(callback, state, pinData, preAllocated, flowExecutionControl);
            }
            catch
            {
                Free(overlapped);
                throw;
            }
            return(overlapped);
        }
        private static unsafe void OnExecutionContextCallback(object state)
        {
            ExecutionContextCallbackArgs args = (ExecutionContextCallbackArgs)state;

            uint errorCode    = args._errorCode;
            uint bytesWritten = args._bytesWritten;
            Win32ThreadPoolNativeOverlapped *overlapped = args._overlapped;
            OverlappedData data = args._data;

            // Put the args object back in the per-thread cache, now that we're done with it.
            args._data = null;
            t_executionContextCallbackArgs = args;

            data._callback(errorCode, bytesWritten, ToNativeOverlapped(overlapped));
        }
        internal static unsafe 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;
                }
            }
        }
Beispiel #10
0
        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;
            }
        }
Beispiel #11
0
        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 static unsafe void CompleteWithCallback(uint errorCode, uint bytesWritten, Win32ThreadPoolNativeOverlapped *overlapped)
        {
            OverlappedData data = overlapped->Data;

            Debug.Assert(!data._completed);
            data._completed = true;

            if (data._executionContext == null)
            {
                data._callback(errorCode, bytesWritten, ToNativeOverlapped(overlapped));
                return;
            }

            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 static unsafe NativeOverlapped *ToNativeOverlapped(Win32ThreadPoolNativeOverlapped *overlapped)
 {
     return((NativeOverlapped *)overlapped);
 }