We need you! We're working hard on the next version of Developer Fusion -
Let us know what you think we should be up to!
- namespace System.Threading
- {
- using System;
- using System.Runtime.InteropServices;
- using System.Runtime.CompilerServices;
- using System.Security;
- using System.Security.Permissions;
- using System.Runtime.ConstrainedExecution;
-
-
-
-
-
- [System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
- [System.Runtime.InteropServices.ComVisible(true)]
- public struct NativeOverlapped
- {
- public IntPtr InternalLow;
- public IntPtr InternalHigh;
- public int OffsetLow;
- public int OffsetHigh;
- public IntPtr EventHandle;
- }
-
- unsafe internal class _IOCompletionCallback
- {
- IOCompletionCallback _ioCompletionCallback;
- ExecutionContext _executionContext;
- uint _errorCode;
-
- uint _numBytes;
-
- NativeOverlapped* _pOVERLAP;
-
- internal _IOCompletionCallback(IOCompletionCallback ioCompletionCallback, ref StackCrawlMark stackMark)
- {
- _ioCompletionCallback = ioCompletionCallback;
-
- _executionContext = ExecutionContext.Capture(ref stackMark);
- ExecutionContext.ClearSyncContext(_executionContext);
- }
-
- static internal ContextCallback _ccb = new ContextCallback(IOCompletionCallback_Context);
- static internal void IOCompletionCallback_Context(object state)
- {
- _IOCompletionCallback helper = (_IOCompletionCallback)state;
- BCLDebug.Assert(helper != null, "_IOCompletionCallback cannot be null");
- helper._ioCompletionCallback(helper._errorCode, helper._numBytes, helper._pOVERLAP);
- }
-
-
-
-
-
-
- unsafe static internal void PerformIOCompletionCallback(uint errorCode, uint numBytes, NativeOverlapped* pOVERLAP)
- {
- Overlapped overlapped = OverlappedData.GetOverlappedFromNative(pOVERLAP).m_overlapped;
- _IOCompletionCallback helper = overlapped.iocbHelper;
-
- if (helper == null || helper._executionContext == null || helper._executionContext.IsDefaultFTContext()) {
-
- IOCompletionCallback callback = overlapped.UserCallback;
- callback(errorCode, numBytes, pOVERLAP);
- }
- else {
-
- helper._errorCode = errorCode;
- helper._numBytes = numBytes;
- helper._pOVERLAP = pOVERLAP;
- ExecutionContext.Run(helper._executionContext.CreateCopy(), _ccb, helper);
- }
- }
- }
-
- internal sealed class OverlappedData : CriticalFinalizerObject
- {
-
-
- internal IAsyncResult m_asyncResult;
- internal IOCompletionCallback m_iocb;
- internal _IOCompletionCallback m_iocbHelper;
- internal Overlapped m_overlapped;
- private object m_userObject;
- internal OverlappedDataCacheLine m_cacheLine;
- private IntPtr m_pinSelf;
- private IntPtr m_userObjectInternal;
- private int m_AppDomainId;
- internal short m_slot;
- #pragma warning disable 414 // Field is not used from managed.
- #pragma warning disable 169
- private byte m_isArray;
- private byte m_toBeCleaned;
- #pragma warning restore 414
- #pragma warning restore 169
- internal NativeOverlapped m_nativeOverlapped;
-
- internal OverlappedData(OverlappedDataCacheLine cacheLine)
- {
- m_cacheLine = cacheLine;
- }
-
- ~OverlappedData()
- {
- if (null != m_cacheLine && false == m_cacheLine.Removed) {
-
-
- if (!Environment.HasShutdownStarted && !AppDomain.CurrentDomain.IsFinalizingForUnload()) {
-
-
-
- OverlappedDataCache.CacheOverlappedData(this);
- GC.ReRegisterForFinalize(this);
- }
- }
- }
-
- internal void ReInitialize()
- {
- m_asyncResult = null;
- m_iocb = null;
- m_iocbHelper = null;
- m_overlapped = null;
- m_userObject = null;
- BCLDebug.Assert(m_pinSelf.IsNull(), "OverlappedData has not been freed: m_pinSelf");
- m_pinSelf = (IntPtr)0;
- m_userObjectInternal = (IntPtr)0;
- BCLDebug.Assert(m_AppDomainId == 0 || m_AppDomainId == AppDomain.CurrentDomain.Id, "OverlappedData is not in the current domain");
- m_AppDomainId = 0;
- m_nativeOverlapped.EventHandle = (IntPtr)0;
- m_isArray = 0;
- m_nativeOverlapped.InternalHigh = (IntPtr)0;
- }
-
- unsafe internal NativeOverlapped* Pack(IOCompletionCallback iocb, object userData)
- {
- if (!m_pinSelf.IsNull()) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_Overlapped_Pack"));
- }
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
-
- if (iocb != null) {
- m_iocbHelper = new _IOCompletionCallback(iocb, ref stackMark);
- m_iocb = iocb;
- }
- else {
- m_iocbHelper = null;
- m_iocb = null;
- }
- m_userObject = userData;
- if (m_userObject != null) {
- if (m_userObject.GetType() == typeof(object[])) {
- m_isArray = 1;
- }
- else {
- m_isArray = 0;
- }
- }
- return AllocateNativeOverlapped();
- }
-
- [SecurityPermissionAttribute(SecurityAction.LinkDemand, ControlEvidence = true, ControlPolicy = true)]
- unsafe internal NativeOverlapped* UnsafePack(IOCompletionCallback iocb, object userData)
- {
- if (!m_pinSelf.IsNull()) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_Overlapped_Pack"));
- }
- m_userObject = userData;
- if (m_userObject != null) {
- if (m_userObject.GetType() == typeof(object[])) {
- m_isArray = 1;
- }
- else {
- m_isArray = 0;
- }
- }
- m_iocb = iocb;
- m_iocbHelper = null;
- return AllocateNativeOverlapped();
- }
-
- [ComVisible(false)]
- internal IntPtr UserHandle {
- get { return m_nativeOverlapped.EventHandle; }
- set { m_nativeOverlapped.EventHandle = value; }
- }
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- unsafe private extern NativeOverlapped* AllocateNativeOverlapped();
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- unsafe static internal extern void FreeNativeOverlapped(NativeOverlapped* nativeOverlappedPtr);
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- unsafe static internal extern OverlappedData GetOverlappedFromNative(NativeOverlapped* nativeOverlappedPtr);
- }
-
- /// <internalonly/>
- [System.Runtime.InteropServices.ComVisible(true)]
- public class Overlapped
- {
- private OverlappedData m_overlappedData;
-
- public Overlapped()
- {
- m_overlappedData = OverlappedDataCache.GetOverlappedData(this);
- }
-
- 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;
- }
-
- [Obsolete("This constructor is not 64-bit compatible. Use the constructor that takes an IntPtr for the event handle. http://go.microsoft.com/fwlink/?linkid=14202")]
- public Overlapped(int offsetLo, int offsetHi, int hEvent, IAsyncResult ar) : this(offsetLo, offsetHi, new IntPtr(hEvent), ar)
- {
- }
-
- public IAsyncResult AsyncResult {
- get { return m_overlappedData.m_asyncResult; }
- set { m_overlappedData.m_asyncResult = value; }
- }
-
- public int OffsetLow {
- get { return m_overlappedData.m_nativeOverlapped.OffsetLow; }
- set { m_overlappedData.m_nativeOverlapped.OffsetLow = value; }
- }
-
- public int OffsetHigh {
- get { return m_overlappedData.m_nativeOverlapped.OffsetHigh; }
- set { m_overlappedData.m_nativeOverlapped.OffsetHigh = value; }
- }
-
- [Obsolete("This property is not 64-bit compatible. Use EventHandleIntPtr instead. http://go.microsoft.com/fwlink/?linkid=14202")]
- public int EventHandle {
- get { return m_overlappedData.UserHandle.ToInt32(); }
- set { m_overlappedData.UserHandle = new IntPtr(value); }
- }
-
- [ComVisible(false)]
- public IntPtr EventHandleIntPtr {
- get { return m_overlappedData.UserHandle; }
- set { m_overlappedData.UserHandle = value; }
- }
-
- internal _IOCompletionCallback iocbHelper {
- get { return m_overlappedData.m_iocbHelper; }
- }
-
- internal IOCompletionCallback UserCallback {
- get { return m_overlappedData.m_iocb; }
- }
-
-
- [Obsolete("This method is not safe. Use Pack (iocb, userData) instead. http://go.microsoft.com/fwlink/?linkid=14202")]
- [CLSCompliant(false)]
- unsafe public NativeOverlapped* Pack(IOCompletionCallback iocb)
- {
- return Pack(iocb, null);
- }
-
- [CLSCompliant(false), ComVisible(false)]
- unsafe public NativeOverlapped* Pack(IOCompletionCallback iocb, object userData)
- {
- return m_overlappedData.Pack(iocb, userData);
- }
-
- [Obsolete("This method is not safe. Use UnsafePack (iocb, userData) instead. http://go.microsoft.com/fwlink/?linkid=14202")]
- [CLSCompliant(false)]
- [SecurityPermissionAttribute(SecurityAction.LinkDemand, ControlEvidence = true, ControlPolicy = true)]
- unsafe public NativeOverlapped* UnsafePack(IOCompletionCallback iocb)
- {
- return UnsafePack(iocb, null);
- }
-
- [CLSCompliant(false), ComVisible(false)]
- [SecurityPermissionAttribute(SecurityAction.LinkDemand, ControlEvidence = true, ControlPolicy = true)]
- unsafe public NativeOverlapped* UnsafePack(IOCompletionCallback iocb, object userData)
- {
- return m_overlappedData.UnsafePack(iocb, userData);
- }
-
-
- [CLSCompliant(false)]
- unsafe public static Overlapped Unpack(NativeOverlapped* nativeOverlappedPtr)
- {
- if (nativeOverlappedPtr == null)
- throw new ArgumentNullException("nativeOverlappedPtr");
-
- Overlapped overlapped = OverlappedData.GetOverlappedFromNative(nativeOverlappedPtr).m_overlapped;
-
- return overlapped;
- }
-
- [CLSCompliant(false)]
- unsafe public static 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);
- }
-
- }
-
-
-
- internal sealed class OverlappedDataCacheLine
- {
- internal OverlappedData[] m_items;
- internal OverlappedDataCacheLine m_next;
- private bool m_removed;
- internal const short CacheSize = 16;
-
- internal OverlappedDataCacheLine()
- {
- m_items = new OverlappedData[OverlappedDataCacheLine.CacheSize];
-
-
- new object();
- for (short i = 0; i < OverlappedDataCacheLine.CacheSize; i++) {
- m_items[i] = new OverlappedData(this);
- m_items[i].m_slot = i;
- }
- new object();
- }
-
- ~OverlappedDataCacheLine()
- {
- m_removed = true;
- }
-
- internal bool Removed {
- get { return m_removed; }
- set { m_removed = value; }
- }
- }
-
- internal sealed class OverlappedDataCache : CriticalFinalizerObject
- {
-
-
- private static OverlappedDataCacheLine m_overlappedDataCache;
- private static int m_overlappedDataCacheAccessed;
- private static int m_cleanupObjectCount;
- private static float m_CleanupThreshold;
- private const float m_CleanupStep = 0.05f;
- private const float m_CleanupInitialThreadhold = 0.3f;
-
- private int m_gen2GCCount;
- private bool m_ready;
-
-
-
-
-
-
- private static void GrowOverlappedDataCache()
- {
- OverlappedDataCacheLine data = new OverlappedDataCacheLine();
- if (m_overlappedDataCache == null) {
-
- if (Interlocked.CompareExchange<OverlappedDataCacheLine>(ref m_overlappedDataCache, data, null) == null) {
-
- new OverlappedDataCache();
- return;
- }
- }
-
-
- if (m_cleanupObjectCount == 0) {
- new OverlappedDataCache();
- }
-
- while (true) {
-
- OverlappedDataCacheLine walk = m_overlappedDataCache;
- while (null != walk && null != walk.m_next) {
-
-
-
-
-
-
-
-
-
-
-
- walk = walk.m_next;
- }
-
-
- if (null == walk)
- return;
-
-
-
-
-
-
-
- if (Interlocked.CompareExchange<OverlappedDataCacheLine>(ref walk.m_next, data, null) == null)
- break;
- }
- }
-
-
- static internal 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();
- }
-
-
-
- }
-
-
- static internal void CacheOverlappedData(OverlappedData data)
- {
- data.ReInitialize();
-
- data.m_cacheLine.m_items[data.m_slot] = data;
- }
-
- internal OverlappedDataCache()
- {
- if (m_cleanupObjectCount == 0) {
- m_CleanupThreshold = m_CleanupInitialThreadhold;
- if (Interlocked.Exchange(ref m_cleanupObjectCount, 1) == 0) {
- m_ready = true;
- }
- }
- }
-
-
- ~OverlappedDataCache()
- {
- if (!m_ready) {
- return;
- }
-
- if (null == m_overlappedDataCache) {
- Interlocked.Exchange(ref m_cleanupObjectCount, 0);
- return;
- }
-
- if (!Environment.HasShutdownStarted && !AppDomain.CurrentDomain.IsFinalizingForUnload()) {
- GC.ReRegisterForFinalize(this);
- }
-
- int gen2GCCount = GC.CollectionCount(GC.MaxGeneration);
- if (gen2GCCount == m_gen2GCCount) {
-
- return;
- }
-
- m_gen2GCCount = gen2GCCount;
-
-
- OverlappedDataCacheLine prev = null;
- OverlappedDataCacheLine walk = m_overlappedDataCache;
- OverlappedDataCacheLine empty = null;
- OverlappedDataCacheLine preempty = prev;
- int total = 0;
- int used = 0;
- while (walk != null) {
- total++;
- bool fUsed = false;
- for (short i = 0; i < OverlappedDataCacheLine.CacheSize; i++) {
- if (walk.m_items[i] == null) {
- fUsed = true;
- used++;
- }
- }
- if (!fUsed) {
- preempty = prev;
- empty = walk;
- }
- prev = walk;
- walk = walk.m_next;
- }
- total *= OverlappedDataCacheLine.CacheSize;
-
- if (null != empty && total * m_CleanupThreshold > used) {
-
-
- if (preempty == null) {
- m_overlappedDataCache = empty.m_next;
- }
- else {
- preempty.m_next = empty.m_next;
- }
-
- empty.Removed = true;
- }
-
- if (m_overlappedDataCacheAccessed != 0) {
- m_CleanupThreshold = m_CleanupInitialThreadhold;
- Interlocked.Exchange(ref m_overlappedDataCacheAccessed, 0);
- }
- else {
- m_CleanupThreshold += m_CleanupStep;
- }
-
-
- }
- }
- }