示例#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);
            }
        }
示例#2
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);
        }
示例#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);
        }
示例#4
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);
        }
示例#5
0
 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);
        }
示例#7
0
        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;
            }
        }
示例#8
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;
            }
        }
        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;
        }