상속: System.Runtime.ConstrainedExecution.CriticalFinalizerObject
예제 #1
0
        //TODO: call from ThreadPool
        internal static unsafe void PerformIOCompletionCallback(uint errorCode, uint numBytes, NativeOverlapped *pNativeOverlapped)
        {
            do
            {
                OverlappedData overlapped = OverlappedData.GetOverlappedFromNative(pNativeOverlapped);

                if (overlapped._callback is IOCompletionCallback iocb)
                {
                    // We got here because of UnsafePack (or) Pack with EC flow suppressed
                    iocb(errorCode, numBytes, pNativeOverlapped);
                }
                else
                {
                    // We got here because of Pack
                    var helper = (_IOCompletionCallback)overlapped._callback !;
                    helper._errorCode         = errorCode;
                    helper._numBytes          = numBytes;
                    helper._pNativeOverlapped = pNativeOverlapped;
                    ExecutionContext.Run(helper._executionContext, s_ccb, helper);
                }

                //Quickly check the VM again, to see if a packet has arrived.
                //OverlappedData.CheckVMForIOPacket(out pOVERLAP, out errorCode, out numBytes);
                pNativeOverlapped = null;
            } while (pNativeOverlapped != null);
        }
        public static void PerformSingleIOCompletionCallback(uint errorCode, uint numBytes, NativeOverlapped *pNativeOverlapped)
        {
            Debug.Assert(pNativeOverlapped != null);

            OverlappedData overlapped = OverlappedData.GetOverlappedFromNative(pNativeOverlapped);
            object?        callback   = overlapped._callback;

            if (callback is IOCompletionCallback iocb)
            {
                // We got here because of UnsafePack (or) Pack with EC flow suppressed
                iocb(errorCode, numBytes, pNativeOverlapped);
                return;
            }

            if (callback == null)
            {
                // A callback was not provided
                return;
            }

            // We got here because of Pack
            Debug.Assert(callback is _IOCompletionCallback);
            var helper = (_IOCompletionCallback)callback;

            helper._errorCode         = errorCode;
            helper._numBytes          = numBytes;
            helper._pNativeOverlapped = pNativeOverlapped;
            ExecutionContext.RunInternal(helper._executionContext, IOCompletionCallback_Context_Delegate, helper);
        }
        internal static void CacheOverlappedData(OverlappedData data)
        {
            data.ReInitialize();

            // this is, by definition, a recently-used object
            s_usedSinceLastGC.Push(data);
        }
예제 #4
0
        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);
        }
예제 #5
0
        // call back helper
        static unsafe internal void PerformIOCompletionCallback(uint errorCode,            // Error code
                                                                uint numBytes,             // No. of bytes transferred
                                                                NativeOverlapped *pOVERLAP // ptr to OVERLAP structure
                                                                )
        {
            Overlapped            overlapped;
            _IOCompletionCallback helper;

            do
            {
                overlapped = OverlappedData.GetOverlappedFromNative(pOVERLAP).m_overlapped;
                helper     = overlapped.iocbHelper;

                if (helper == null || helper._executionContext == null || helper._executionContext == ExecutionContext.Default)
                {
                    // We got here because of UnsafePack (or) Pack with EC flow supressed
                    IOCompletionCallback callback = overlapped.UserCallback;
                    callback(errorCode, numBytes, pOVERLAP);
                }
                else
                {
                    // We got here because of Pack
                    helper._errorCode = errorCode;
                    helper._numBytes  = numBytes;
                    helper._pOVERLAP  = pOVERLAP;
                    ExecutionContext.Run(helper._executionContext, _ccb, helper);
                }

                //Quickly check the VM again, to see if a packet has arrived.
                OverlappedData.CheckVMForIOPacket(out pOVERLAP, out errorCode, out numBytes);
            } while (pOVERLAP != null);
        }
예제 #6
0
        // call back helper
        internal static unsafe void PerformIOCompletionCallback(uint errorCode, uint numBytes, NativeOverlapped *pNativeOverlapped)
        {
            do
            {
                OverlappedData overlapped = OverlappedData.GetOverlappedFromNative(pNativeOverlapped);

                if (overlapped._callback is IOCompletionCallback iocb)
                {
                    // We got here because of UnsafePack (or) Pack with EC flow suppressed
                    iocb(errorCode, numBytes, pNativeOverlapped);
                }
                else
                {
                    // We got here because of Pack
                    var helper = (_IOCompletionCallback?)overlapped._callback;
                    Debug.Assert(helper != null, "Should only be receiving a completion callback if a delegate was provided.");
                    helper._errorCode         = errorCode;
                    helper._numBytes          = numBytes;
                    helper._pNativeOverlapped = pNativeOverlapped;
                    ExecutionContext.RunInternal(helper._executionContext, _ccb, helper);
                }

                //Quickly check the VM again, to see if a packet has arrived.
                OverlappedData.CheckVMForIOPacket(out pNativeOverlapped, out errorCode, out numBytes);
            } while (pNativeOverlapped != null);
        }
예제 #7
0
        internal static OverlappedData GetOverlappedData(Overlapped overlapped)
        {
            OverlappedData data = null;

            Interlocked.Exchange(ref m_overlappedDataCacheAccessed, 1);
            while (true)
            {
                OverlappedDataCacheLine overlappedDataCache = s_firstFreeCacheLine;
                if (overlappedDataCache == null)
                {
                    overlappedDataCache = m_overlappedDataCache;
                }
                while (overlappedDataCache != null)
                {
                    for (short i = 0; i < 0x10; i = (short)(i + 1))
                    {
                        if (overlappedDataCache.m_items[i] != null)
                        {
                            data = Interlocked.Exchange <OverlappedData>(ref overlappedDataCache.m_items[i], null);
                            if (data != null)
                            {
                                s_firstFreeCacheLine = overlappedDataCache;
                                data.m_overlapped    = overlapped;
                                return(data);
                            }
                        }
                    }
                    overlappedDataCache = overlappedDataCache.m_next;
                }
                GrowOverlappedDataCache();
            }
        }
예제 #8
0
 public static unsafe Overlapped Unpack(NativeOverlapped *nativeOverlappedPtr)
 {
     if ((IntPtr)nativeOverlappedPtr == IntPtr.Zero)
     {
         throw new ArgumentNullException("nativeOverlappedPtr");
     }
     return(OverlappedData.GetOverlappedFromNative(nativeOverlappedPtr).m_overlapped);
 }
 public Overlapped(int offsetLo, int offsetHi, IntPtr hEvent, IAsyncResult ar)
 {
     m_overlappedData = OverlappedDataCache.GetOverlappedData(this);
     m_overlappedData.m_nativeOverlapped.OffsetLow  = offsetLo;
     m_overlappedData.m_nativeOverlapped.OffsetHigh = offsetHi;
     m_overlappedData.UserHandle    = hEvent;
     m_overlappedData.m_asyncResult = ar;
 }
예제 #10
0
 public Overlapped(int offsetLo, int offsetHi, IntPtr hEvent, IAsyncResult ar)
 {
     this.m_overlappedData = OverlappedDataCache.GetOverlappedData(this);
     this.m_overlappedData.m_nativeOverlapped.OffsetLow = offsetLo;
     this.m_overlappedData.m_nativeOverlapped.OffsetHigh = offsetHi;
     this.m_overlappedData.UserHandle = hEvent;
     this.m_overlappedData.m_asyncResult = ar;
 }
예제 #11
0
 public Overlapped(int offsetLo, int offsetHi, IntPtr hEvent, IAsyncResult ar)
 {
     m_overlappedData = (OverlappedData)s_overlappedDataCache.Allocate();
     m_overlappedData.m_overlapped = this;
     m_overlappedData.m_nativeOverlapped.OffsetLow  = offsetLo;
     m_overlappedData.m_nativeOverlapped.OffsetHigh = offsetHi;
     m_overlappedData.UserHandle    = hEvent;
     m_overlappedData.m_asyncResult = ar;
 }
예제 #12
0
        private static unsafe void CalculateNativeOverlappedOffset()
        {
            OverlappedData overlappedData = new OverlappedData();

            fixed(IntPtr *pEETypePtr = &overlappedData.m_pEEType)
            fixed(NativeOverlapped * pNativeOverlapped = &overlappedData.m_nativeOverlapped)
            {
                s_nativeOverlappedOffset = (int)((byte *)pNativeOverlapped - (byte *)pEETypePtr);
            }
        }
        private void SetData(IOCompletionCallback callback, object state, object pinData, PreAllocatedOverlapped preAllocated, bool flowExecutionContext)
        {
            Debug.Assert(callback != null);

            OverlappedData data = Data;

            data._callback         = callback;
            data._state            = state;
            data._executionContext = flowExecutionContext ? ExecutionContext.Capture() : null;
            data._preAllocated     = preAllocated;

            //
            // pinData can be any blittable type to be pinned, *or* an instance of object[] each element of which refers to
            // an instance of a blittable type to be pinned.
            //
            if (pinData != null)
            {
                object[] objArray = pinData as object[];
                if (objArray != null && objArray.GetType() == typeof(object[]))
                {
                    if (data._pinnedData == null || data._pinnedData.Length < objArray.Length)
                    {
                        Array.Resize(ref data._pinnedData, objArray.Length);
                    }

                    for (int i = 0; i < objArray.Length; i++)
                    {
                        if (!data._pinnedData[i].IsAllocated)
                        {
                            data._pinnedData[i] = GCHandle.Alloc(objArray[i], GCHandleType.Pinned);
                        }
                        else
                        {
                            data._pinnedData[i].Target = objArray[i];
                        }
                    }
                }
                else
                {
                    if (data._pinnedData == null)
                    {
                        data._pinnedData = new GCHandle[1];
                    }

                    if (!data._pinnedData[0].IsAllocated)
                    {
                        data._pinnedData[0] = GCHandle.Alloc(pinData, GCHandleType.Pinned);
                    }
                    else
                    {
                        data._pinnedData[0].Target = pinData;
                    }
                }
            }
        }
예제 #14
0
        public static unsafe Overlapped Unpack(NativeOverlapped *nativeOverlappedPtr)
        {
            if (nativeOverlappedPtr == null)
            {
                throw new ArgumentNullException(nameof(nativeOverlappedPtr));
            }

            Overlapped overlapped = OverlappedData.GetOverlappedFromNative(nativeOverlappedPtr).m_overlapped;

            return(overlapped);
        }
        unsafe public static Overlapped Unpack(NativeOverlapped *nativeOverlappedPtr)
        {
            if (nativeOverlappedPtr == null)
            {
                throw new ArgumentNullException("nativeOverlappedPtr");
            }
            Contract.EndContractBlock();

            Overlapped overlapped = OverlappedData.GetOverlappedFromNative(nativeOverlappedPtr).m_overlapped;

            return(overlapped);
        }
 internal OverlappedDataCacheLine()
 {
     m_items = new OverlappedData[OverlappedDataCacheLine.CacheSize];
     // Allocate some dummy objects before and after the cacheLine.
     // These objects will allow GC to move two cacheLine's closer.
     new Object();
     for (short i = 0; i < OverlappedDataCacheLine.CacheSize; i++)
     {
         m_items[i]        = new OverlappedData(this);
         m_items[i].m_slot = i;
     }
     new Object();
 }
예제 #17
0
        public static unsafe void Free(NativeOverlapped *nativeOverlappedPtr)
        {
            if (nativeOverlappedPtr == null)
            {
                throw new ArgumentNullException("nativeOverlappedPtr");
            }
            Overlapped overlapped = OverlappedData.GetOverlappedFromNative(nativeOverlappedPtr).m_overlapped;

            OverlappedData.FreeNativeOverlapped(nativeOverlappedPtr);
            OverlappedData overlappedData = overlapped.m_overlappedData;

            overlapped.m_overlappedData = null;
            OverlappedDataCache.CacheOverlappedData(overlappedData);
        }
        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));
        }
예제 #19
0
        public static unsafe void Free(NativeOverlapped *nativeOverlappedPtr)
        {
            if (nativeOverlappedPtr == null)
            {
                throw new ArgumentNullException(nameof(nativeOverlappedPtr));
            }

            Overlapped overlapped = OverlappedData.GetOverlappedFromNative(nativeOverlappedPtr).m_overlapped;

            OverlappedData.FreeNativeOverlapped(nativeOverlappedPtr);
            OverlappedData overlappedData = overlapped.m_overlappedData;

            overlapped.m_overlappedData = null;
            overlappedData.ReInitialize();
            s_overlappedDataCache.Free(overlappedData);
        }
        //
        // Retrieve an OverlappedData from the cache, or create a new one
        //
        internal static OverlappedData GetOverlappedData(Overlapped overlapped)
        {
            EnsureFinalizerRegistered();

            OverlappedData result = null;

            //
            // First, try to pop a recently-used object.
            //
            ConcurrentStack <OverlappedData> stack = s_usedSinceLastGC;

            stack.TryPop(out result);

            //
            // If we didn't get one, try to resurrect an older one.
            //
            if (result == null)
            {
                stack = s_notUsedSinceLastGC;
                if (stack != null)
                {
                    stack.TryPop(out result);
                }
            }

            //
            // We didn't find anything in the cache, so we need to create a new instance.
            //
            if (result == null)
            {
                //
                // To reduce fragmentation, we'll create a whole batch of these, and cache all but the one
                // we return.  Because we're allocating the batch all at once, it is likely that all instances
                // will be contiguous in memory.
                //
                for (int i = 0; i < BatchSize - 1; i++)
                {
                    s_usedSinceLastGC.Push(new OverlappedData());
                }

                result = new OverlappedData();
            }

            result.m_overlapped = overlapped;
            return(result);
        }
예제 #21
0
        unsafe public static void Free(NativeOverlapped *nativeOverlappedPtr)
        {
            if (nativeOverlappedPtr == null)
            {
                throw new ArgumentNullException("nativeOverlappedPtr");
            }
            Contract.EndContractBlock();

            Overlapped overlapped = OverlappedData.GetOverlappedFromNative(nativeOverlappedPtr).m_overlapped;

            OverlappedData.FreeNativeOverlapped(nativeOverlappedPtr);
            OverlappedData overlappedData = overlapped.m_overlappedData;

            overlapped.m_overlappedData = null;
            overlappedData.ReInitialize();
            s_overlappedDataCache.Free(overlappedData);
        }
예제 #22
0
        public static unsafe void Free(NativeOverlapped *nativeOverlappedPtr)
        {
            if ((IntPtr)nativeOverlappedPtr == IntPtr.Zero)
            {
                throw new ArgumentNullException("nativeOverlappedPtr");
            }
            Overlapped overlapped = OverlappedData.GetOverlappedFromNative(nativeOverlappedPtr).m_overlapped;

            OverlappedData.FreeNativeOverlapped(nativeOverlappedPtr);
            OverlappedData overlappedData = overlapped.m_overlappedData;
            // ISSUE: variable of the null type
            __Null local = null;

            overlapped.m_overlappedData = (OverlappedData)local;
            overlappedData.ReInitialize();
            Overlapped.s_overlappedDataCache.Free((object)overlappedData);
        }
예제 #23
0
 internal static unsafe void PerformIOCompletionCallback(uint errorCode, uint numBytes, NativeOverlapped *pOVERLAP)
 {
     do
     {
         Overlapped            overlapped = OverlappedData.GetOverlappedFromNative(pOVERLAP).m_overlapped;
         _IOCompletionCallback iocbHelper = overlapped.iocbHelper;
         if (((iocbHelper == null) || (iocbHelper._executionContext == null)) || iocbHelper._executionContext.IsDefaultFTContext())
         {
             overlapped.UserCallback(errorCode, numBytes, pOVERLAP);
         }
         else
         {
             iocbHelper._errorCode = errorCode;
             iocbHelper._numBytes  = numBytes;
             iocbHelper._pOVERLAP  = pOVERLAP;
             ExecutionContext.Run(iocbHelper._executionContext.CreateCopy(), _ccb, iocbHelper);
         }
         OverlappedData.CheckVMForIOPacket(out pOVERLAP, out errorCode, out numBytes);
     }while (pOVERLAP != null);
 }
예제 #24
0
 internal static unsafe void PerformIOCompletionCallback(uint errorCode, uint numBytes, NativeOverlapped *pOVERLAP)
 {
     do
     {
         Overlapped            overlapped = OverlappedData.GetOverlappedFromNative(pOVERLAP).m_overlapped;
         _IOCompletionCallback iocbHelper = overlapped.iocbHelper;
         if (iocbHelper == null || iocbHelper._executionContext == null || iocbHelper._executionContext.IsDefaultFTContext(true))
         {
             overlapped.UserCallback(errorCode, numBytes, pOVERLAP);
         }
         else
         {
             iocbHelper._errorCode = errorCode;
             iocbHelper._numBytes  = numBytes;
             iocbHelper._pOVERLAP  = pOVERLAP;
             using (ExecutionContext copy = iocbHelper._executionContext.CreateCopy())
                 ExecutionContext.Run(copy, _IOCompletionCallback._ccb, (object)iocbHelper, true);
         }
         OverlappedData.CheckVMForIOPacket(out pOVERLAP, out errorCode, out numBytes);
     }while ((IntPtr)pOVERLAP != IntPtr.Zero);
 }
        // call back helper
        static unsafe internal void PerformIOCompletionCallback(uint errorCode,            // Error code
                                                                uint numBytes,             // No. of bytes transferred
                                                                NativeOverlapped *pOVERLAP // ptr to OVERLAP structure
                                                                )
        {
            Overlapped            overlapped = OverlappedData.GetOverlappedFromNative(pOVERLAP).m_overlapped;
            _IOCompletionCallback helper     = overlapped.iocbHelper;

            if (helper == null || helper._executionContext == null || helper._executionContext.IsDefaultFTContext())
            {
                // We got here because of UnsafePack (or) Pack with EC flow supressed
                IOCompletionCallback callback = overlapped.UserCallback;
                callback(errorCode, numBytes, pOVERLAP);
            }
            else
            {
                // We got here because of Pack
                helper._errorCode = errorCode;
                helper._numBytes  = numBytes;
                helper._pOVERLAP  = pOVERLAP;
                ExecutionContext.Run(helper._executionContext.CreateCopy(), _ccb, helper);
            }
        }
        internal static OverlappedData GetOverlappedData(Overlapped overlapped)
        {
            OverlappedData overlappedData = null;

            Interlocked.Exchange(ref m_overlappedDataCacheAccessed, 1);

            while (true)
            {
                OverlappedDataCacheLine walk = m_overlappedDataCache;
                while (null != walk)
                {
                    for (short i = 0; i < OverlappedDataCacheLine.CacheSize; i++)
                    {
                        if (walk.m_items[i] != null)
                        {
                            overlappedData = Interlocked.Exchange <OverlappedData>(ref walk.m_items[i], null);
                            if (overlappedData != null)
                            {
                                overlappedData.m_overlapped = overlapped;
                                return(overlappedData);
                            }
                        }
                    }

                    walk = walk.m_next;
                }

                GrowOverlappedDataCache();
            }

            /*
             * Interlocked.Increment(ref m_Total);
             * Console.WriteLine("OverlappedDataCache get " + m_Total +
             *                " create " + m_Create +
             *                " Cache " + m_Cache);
             */
        }
        private static unsafe Win32ThreadPoolNativeOverlapped *AllocateNew()
        {
            IntPtr freePtr;
            Win32ThreadPoolNativeOverlapped *overlapped;
            OverlappedData data;

            // Find a free Overlapped
            while ((freePtr = Volatile.Read(ref s_freeList)) != IntPtr.Zero)
            {
                overlapped = (Win32ThreadPoolNativeOverlapped *)freePtr;

                if (Interlocked.CompareExchange(ref s_freeList, overlapped->_nextFree, freePtr) != freePtr)
                {
                    continue;
                }

                overlapped->_nextFree = IntPtr.Zero;
                return(overlapped);
            }

            // None are free; allocate a new one.
            overlapped = (Win32ThreadPoolNativeOverlapped *)Marshal.AllocHGlobal(sizeof(Win32ThreadPoolNativeOverlapped));
            *overlapped = default(Win32ThreadPoolNativeOverlapped);

            // Allocate a OverlappedData object, and an index at which to store it in _dataArray.
            data = new OverlappedData();
            int dataIndex = Interlocked.Increment(ref s_dataCount) - 1;

            // Make sure we didn't wrap around.
            if (dataIndex < 0)
            {
                Environment.FailFast("Too many outstanding Win32ThreadPoolNativeOverlapped instances");
            }

            while (true)
            {
                OverlappedData[] dataArray = Volatile.Read(ref s_dataArray);
                int currentLength          = dataArray == null ? 0 : dataArray.Length;

                // If the current array is too small, create a new, larger one.
                if (currentLength <= dataIndex)
                {
                    int newLength = currentLength;
                    if (newLength == 0)
                    {
                        newLength = 128;
                    }
                    while (newLength <= dataIndex)
                    {
                        newLength = (newLength * 3) / 2;
                    }

                    OverlappedData[] newDataArray = dataArray;
                    Array.Resize(ref newDataArray, newLength);

                    if (Interlocked.CompareExchange(ref s_dataArray, newDataArray, dataArray) != dataArray)
                    {
                        continue; // Someone else got the free one, try again
                    }
                    dataArray = newDataArray;
                }

                // If we haven't stored this object in the array yet, do so now.  Then we need to make another pass through
                // the loop, in case another thread resized the array before we made this update.
                if (s_dataArray[dataIndex] == null)
                {
                    // Full fence so this write can't move past subsequent reads.
                    Interlocked.Exchange(ref dataArray[dataIndex], data);
                    continue;
                }

                // We're already in the array, so we're done.
                Debug.Assert(dataArray[dataIndex] == data);
                overlapped->_dataIndex = dataIndex;
                return(overlapped);
            }
        }
예제 #28
0
 public Overlapped()
 {
     m_overlappedData = (OverlappedData)s_overlappedDataCache.Allocate();
     m_overlappedData.m_overlapped = this;
 }
예제 #29
0
        internal static void CacheOverlappedData(OverlappedData data)
        {
            data.ReInitialize();

            // this is, by definition, a recently-used object
            s_usedSinceLastGC.Push(data);
        }
예제 #30
0
        //
        // Retrieve an OverlappedData from the cache, or create a new one
        //
        internal static OverlappedData GetOverlappedData(Overlapped overlapped)
        {
            EnsureFinalizerRegistered();

            OverlappedData result = null;

            //
            // First, try to pop a recently-used object.
            //
            ConcurrentStack<OverlappedData> stack = s_usedSinceLastGC;
            stack.TryPop(out result);

            //
            // If we didn't get one, try to resurrect an older one.
            //
            if (result == null)
            {
                stack = s_notUsedSinceLastGC;
                if (stack != null)
                    stack.TryPop(out result);
            }

            //
            // We didn't find anything in the cache, so we need to create a new instance.
            //
            if (result == null)
            {
                //
                // To reduce fragmentation, we'll create a whole batch of these, and cache all but the one
                // we return.  Because we're allocating the batch all at once, it is likely that all instances
                // will be contiguous in memory.
                //
                for (int i = 0; i < BatchSize - 1; i++)
                    s_usedSinceLastGC.Push(new OverlappedData());

                result = new OverlappedData();
            }

            result.m_overlapped = overlapped;
            return result;
        }
예제 #31
0
        internal static unsafe void FreeNativeOverlapped(NativeOverlapped *nativeOverlappedPtr)
        {
            OverlappedData overlappedData = OverlappedData.GetOverlappedFromNative(nativeOverlappedPtr);

            overlappedData.FreeNativeOverlapped();
        }
예제 #32
0
 public Overlapped() 
 {
     m_overlappedData = OverlappedDataCache.GetOverlappedData(this);
 }
예제 #33
0
 internal static void CacheOverlappedData(OverlappedData data)
 {
     data.ReInitialize();
     data.m_cacheLine.m_items[data.m_slot] = data;
     s_firstFreeCacheLine = null;
 }
예제 #34
0
 internal OverlappedDataCacheLine()
 {
     m_items = new OverlappedData[OverlappedDataCacheLine.CacheSize];
     // Allocate some dummy objects before and after the cacheLine.
     // These objects will allow GC to move two cacheLine's closer.
     new Object();
     for (short i = 0; i < OverlappedDataCacheLine.CacheSize; i ++)
     {
         m_items[i] = new OverlappedData (this);
         m_items[i].m_slot = i;
     }
     new Object();
 }
예제 #35
0
 public Overlapped() 
 {
     m_overlappedData = (OverlappedData) s_overlappedDataCache.Allocate();
     m_overlappedData.m_overlapped = this;
 }
예제 #36
0
 public Overlapped(int offsetLo, int offsetHi, IntPtr hEvent, IAsyncResult ar)
 {
     m_overlappedData = (OverlappedData) s_overlappedDataCache.Allocate();
     m_overlappedData.m_overlapped = this;
     m_overlappedData.m_nativeOverlapped.OffsetLow = offsetLo;
     m_overlappedData.m_nativeOverlapped.OffsetHigh = offsetHi;
     m_overlappedData.UserHandle = hEvent;
     m_overlappedData.m_asyncResult = ar;
 }
        [System.Security.SecuritySafeCritical]  // auto-generated
#endif
        public Overlapped()
        {
            m_overlappedData = OverlappedDataCache.GetOverlappedData(this);
        }
예제 #38
0
 internal static void CacheOverlappedData(OverlappedData data)
 {
     data.ReInitialize();
     data.m_cacheLine.m_items[data.m_slot] = data;
     s_firstFreeCacheLine = null;
 }
        private unsafe static Win32ThreadPoolNativeOverlapped* AllocateNew()
        {
            IntPtr freePtr;
            Win32ThreadPoolNativeOverlapped* overlapped;
            OverlappedData data;

            // Find a free Overlapped
            while ((freePtr = Volatile.Read(ref s_freeList)) != IntPtr.Zero)
            {
                overlapped = (Win32ThreadPoolNativeOverlapped*)freePtr;

                if (Interlocked.CompareExchange(ref s_freeList, overlapped->_nextFree, freePtr) != freePtr)
                    continue;

                overlapped->_nextFree = IntPtr.Zero;
                return overlapped;
            }

            // None are free; allocate a new one.
            overlapped = (Win32ThreadPoolNativeOverlapped*)Marshal.AllocHGlobal(sizeof(Win32ThreadPoolNativeOverlapped));
            *overlapped = default(Win32ThreadPoolNativeOverlapped);

            // Allocate a OverlappedData object, and an index at which to store it in _dataArray.
            data = new OverlappedData();
            int dataIndex = Interlocked.Increment(ref s_dataCount) - 1;

            // Make sure we didn't wrap around.
            if (dataIndex < 0)
                Environment.FailFast("Too many outstanding Win32ThreadPoolNativeOverlapped instances");

            while (true)
            {
                OverlappedData[] dataArray = Volatile.Read(ref s_dataArray);
                int currentLength = dataArray == null ? 0 : dataArray.Length;

                // If the current array is too small, create a new, larger one.
                if (currentLength <= dataIndex)
                {
                    int newLength = currentLength;
                    if (newLength == 0)
                        newLength = 128;
                    while (newLength <= dataIndex)
                        newLength = (newLength * 3) / 2;

                    OverlappedData[] newDataArray = dataArray;
                    Array.Resize(ref newDataArray, newLength);

                    if (Interlocked.CompareExchange(ref s_dataArray, newDataArray, dataArray) != dataArray)
                        continue; // Someone else got the free one, try again

                    dataArray = newDataArray;
                }

                // If we haven't stored this object in the array yet, do so now.  Then we need to make another pass through
                // the loop, in case another thread resized the array before we made this update.
                if (s_dataArray[dataIndex] == null)
                {
                    // Full fence so this write can't move past subsequent reads.
                    Interlocked.Exchange(ref dataArray[dataIndex], data);
                    continue;
                }

                // We're already in the array, so we're done.
                Debug.Assert(dataArray[dataIndex] == data);
                overlapped->_dataIndex = dataIndex;
                return overlapped;
            }
        }