diff options
Diffstat (limited to 'src/mscorlib/src/System/Threading/ThreadPool.cs')
-rw-r--r-- | src/mscorlib/src/System/Threading/ThreadPool.cs | 259 |
1 files changed, 128 insertions, 131 deletions
diff --git a/src/mscorlib/src/System/Threading/ThreadPool.cs b/src/mscorlib/src/System/Threading/ThreadPool.cs index adf0615819..0084050c43 100644 --- a/src/mscorlib/src/System/Threading/ThreadPool.cs +++ b/src/mscorlib/src/System/Threading/ThreadPool.cs @@ -33,8 +33,6 @@ namespace System.Threading public static readonly int processorCount = Environment.ProcessorCount; - public static readonly bool tpHosted = ThreadPool.IsThreadPoolHosted(); - public static volatile bool vmTpInitialized; public static bool enableWorkerTracking; @@ -124,7 +122,7 @@ namespace System.Threading private volatile int m_headIndex = START_INDEX; private volatile int m_tailIndex = START_INDEX; - private SpinLock m_foreignLock = new SpinLock(enableThreadOwnerTracking:false); + private SpinLock m_foreignLock = new SpinLock(enableThreadOwnerTracking: false); public void LocalPush(IThreadPoolWorkItem obj) { @@ -158,7 +156,7 @@ namespace System.Threading finally { if (lockTaken) - m_foreignLock.Exit(useMemoryBarrier:true); + m_foreignLock.Exit(useMemoryBarrier: true); } } @@ -200,7 +198,7 @@ namespace System.Threading finally { if (lockTaken) - m_foreignLock.Exit(useMemoryBarrier:false); + m_foreignLock.Exit(useMemoryBarrier: false); } } } @@ -254,7 +252,7 @@ namespace System.Threading finally { if (lockTaken) - m_foreignLock.Exit(useMemoryBarrier:false); + m_foreignLock.Exit(useMemoryBarrier: false); } } } @@ -321,7 +319,7 @@ namespace System.Threading finally { if (lockTaken) - m_foreignLock.Exit(useMemoryBarrier:false); + m_foreignLock.Exit(useMemoryBarrier: false); } } } @@ -366,7 +364,7 @@ namespace System.Threading finally { if (taken) - m_foreignLock.Exit(useMemoryBarrier:false); + m_foreignLock.Exit(useMemoryBarrier: false); } missedSteal = true; @@ -381,10 +379,10 @@ namespace System.Threading internal readonly ConcurrentQueue<IThreadPoolWorkItem> workItems = new ConcurrentQueue<IThreadPoolWorkItem>(); private volatile int numOutstandingThreadRequests = 0; - + public ThreadPoolWorkQueue() { - loggingEnabled = FrameworkEventSource.Log.IsEnabled(EventLevel.Verbose, FrameworkEventSource.Keywords.ThreadPool|FrameworkEventSource.Keywords.ThreadTransfer); + loggingEnabled = FrameworkEventSource.Log.IsEnabled(EventLevel.Verbose, FrameworkEventSource.Keywords.ThreadPool | FrameworkEventSource.Keywords.ThreadTransfer); } public ThreadPoolWorkQueueThreadLocals EnsureCurrentThreadHasQueue() => @@ -401,7 +399,7 @@ namespace System.Threading int count = numOutstandingThreadRequests; while (count < ThreadPoolGlobals.processorCount) { - int prev = Interlocked.CompareExchange(ref numOutstandingThreadRequests, count+1, count); + int prev = Interlocked.CompareExchange(ref numOutstandingThreadRequests, count + 1, count); if (prev == count) { ThreadPool.RequestWorkerThread(); @@ -439,7 +437,7 @@ namespace System.Threading ThreadPoolWorkQueueThreadLocals tl = null; if (!forceGlobal) tl = ThreadPoolWorkQueueThreadLocals.threadLocals; - + if (null != tl) { tl.workStealingQueue.LocalPush(callback); @@ -511,7 +509,7 @@ namespace System.Threading workQueue.MarkThreadRequestSatisfied(); // Has the desire for logging changed since the last time we entered? - workQueue.loggingEnabled = FrameworkEventSource.Log.IsEnabled(EventLevel.Verbose, FrameworkEventSource.Keywords.ThreadPool|FrameworkEventSource.Keywords.ThreadTransfer); + workQueue.loggingEnabled = FrameworkEventSource.Log.IsEnabled(EventLevel.Verbose, FrameworkEventSource.Keywords.ThreadPool | FrameworkEventSource.Keywords.ThreadTransfer); // // Assume that we're going to need another thread if this one returns to the VM. We'll set this to @@ -603,7 +601,7 @@ namespace System.Threading // who waits for the task to complete. // workItem?.MarkAborted(tae); - + // // In this case, the VM is going to request another thread on our behalf. No need to do it twice. // @@ -707,7 +705,7 @@ namespace System.Threading private volatile int m_lock = 0; internal IntPtr GetHandle() => registeredWaitHandle; - + internal void SetHandle(IntPtr handle) { registeredWaitHandle = handle; @@ -731,7 +729,7 @@ namespace System.Threading } internal bool Unregister( - WaitHandle waitObject // object to be notified when all callbacks to delegates have completed + WaitHandle waitObject // object to be notified when all callbacks to delegates have completed ) { bool result = false; @@ -745,7 +743,7 @@ namespace System.Threading // lock(this) cannot be used reliably in Cer since thin lock could be // promoted to syncblock and that is not a guaranteed operation bool bLockTaken = false; - do + do { if (Interlocked.CompareExchange(ref m_lock, 1, 0) == 0) { @@ -807,8 +805,8 @@ namespace System.Threading // This will result in a "leak" of sorts (since the handle will not be cleaned up) // but the process is exiting anyway. // - // During AD-unload, we don’t finalize live objects until all threads have been - // aborted out of the AD. Since these locked regions are CERs, we won’t abort them + // During AD-unload, we don�t finalize live objects until all threads have been + // aborted out of the AD. Since these locked regions are CERs, we won�t abort them // while the lock is held. So there should be no leak on AD-unload. // if (Interlocked.CompareExchange(ref m_lock, 1, 0) == 0) @@ -841,9 +839,10 @@ namespace System.Threading private static extern bool UnregisterWaitNative(IntPtr handle, SafeHandle waitObject); } - public sealed class RegisteredWaitHandle : MarshalByRefObject { + public sealed class RegisteredWaitHandle : MarshalByRefObject + { private readonly RegisteredWaitHandleSafe internalRegisteredWait; - + internal RegisteredWaitHandle() { internalRegisteredWait = new RegisteredWaitHandleSafe(); @@ -851,23 +850,23 @@ namespace System.Threading internal void SetHandle(IntPtr handle) { - internalRegisteredWait.SetHandle(handle); + internalRegisteredWait.SetHandle(handle); } internal void SetWaitObject(WaitHandle waitObject) { - internalRegisteredWait.SetWaitObject(waitObject); + internalRegisteredWait.SetWaitObject(waitObject); } // This is the only public method on this class public bool Unregister( - WaitHandle waitObject // object to be notified when all callbacks to delegates have completed + WaitHandle waitObject // object to be notified when all callbacks to delegates have completed ) { return internalRegisteredWait.Unregister(waitObject); } } - + public delegate void WaitCallback(Object state); public delegate void WaitOrTimerCallback(Object state, bool timedOut); // signalled or timed out @@ -905,16 +904,16 @@ namespace System.Threading private readonly Object state; #if DEBUG - volatile int executed; + private volatile int executed; ~QueueUserWorkItemCallback() { Debug.Assert( - executed != 0 || Environment.HasShutdownStarted || AppDomain.CurrentDomain.IsFinalizingForUnload(), + executed != 0 || Environment.HasShutdownStarted || AppDomain.CurrentDomain.IsFinalizingForUnload(), "A QueueUserWorkItemCallback was never called!"); } - void MarkExecuted(bool aborted) + private void MarkExecuted(bool aborted) { GC.SuppressFinalize(this); Debug.Assert( @@ -933,7 +932,7 @@ namespace System.Threading void IThreadPoolWorkItem.ExecuteWorkItem() { #if DEBUG - MarkExecuted(aborted:false); + MarkExecuted(aborted: false); #endif // call directly if it is an unsafe call OR EC flow is suppressed if (context == null) @@ -953,7 +952,7 @@ namespace System.Threading #if DEBUG // this workitem didn't execute because we got a ThreadAbortException prior to the call to ExecuteWorkItem. // This counts as being executed for our purposes. - MarkExecuted(aborted:true); + MarkExecuted(aborted: true); #endif } @@ -983,7 +982,7 @@ namespace System.Threading "A QueueUserWorkItemCallbackDefaultContext was never called!"); } - void MarkExecuted(bool aborted) + private void MarkExecuted(bool aborted) { GC.SuppressFinalize(this); Debug.Assert( @@ -1001,7 +1000,7 @@ namespace System.Threading void IThreadPoolWorkItem.ExecuteWorkItem() { #if DEBUG - MarkExecuted(aborted:false); + MarkExecuted(aborted: false); #endif ExecutionContext.Run(ExecutionContext.Default, ccb, this); } @@ -1011,7 +1010,7 @@ namespace System.Threading #if DEBUG // this workitem didn't execute because we got a ThreadAbortException prior to the call to ExecuteWorkItem. // This counts as being executed for our purposes. - MarkExecuted(aborted:true); + MarkExecuted(aborted: true); #endif } @@ -1029,9 +1028,9 @@ namespace System.Threading internal class _ThreadPoolWaitOrTimerCallback { - WaitOrTimerCallback _waitOrTimerCallback; - ExecutionContext _executionContext; - Object _state; + private WaitOrTimerCallback _waitOrTimerCallback; + private ExecutionContext _executionContext; + private Object _state; private static readonly ContextCallback _ccbt = new ContextCallback(WaitOrTimerCallback_Context_t); private static readonly ContextCallback _ccbf = new ContextCallback(WaitOrTimerCallback_Context_f); @@ -1046,23 +1045,23 @@ namespace System.Threading _executionContext = ExecutionContext.Capture(); } } - + private static void WaitOrTimerCallback_Context_t(Object state) => - WaitOrTimerCallback_Context(state, timedOut:true); + WaitOrTimerCallback_Context(state, timedOut: true); private static void WaitOrTimerCallback_Context_f(Object state) => - WaitOrTimerCallback_Context(state, timedOut:false); + WaitOrTimerCallback_Context(state, timedOut: false); private static void WaitOrTimerCallback_Context(Object state, bool timedOut) { _ThreadPoolWaitOrTimerCallback helper = (_ThreadPoolWaitOrTimerCallback)state; helper._waitOrTimerCallback(helper._state, timedOut); } - + // call back helper internal static void PerformWaitOrTimerCallback(Object state, bool timedOut) { - _ThreadPoolWaitOrTimerCallback helper = (_ThreadPoolWaitOrTimerCallback)state; + _ThreadPoolWaitOrTimerCallback helper = (_ThreadPoolWaitOrTimerCallback)state; Debug.Assert(helper != null, "Null state passed to PerformWaitOrTimerCallback!"); // call directly if it is an unsafe call OR EC flow is suppressed if (helper._executionContext == null) @@ -1074,15 +1073,14 @@ namespace System.Threading { ExecutionContext.Run(helper._executionContext, timedOut ? _ccbt : _ccbf, helper); } - } - + } } [CLSCompliant(false)] unsafe public delegate void IOCompletionCallback(uint errorCode, // Error code uint numBytes, // No. of bytes transferred NativeOverlapped* pOVERLAP // ptr to OVERLAP structure - ); + ); public static class ThreadPool { @@ -1112,42 +1110,42 @@ namespace System.Threading } [CLSCompliant(false)] - [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod public static RegisteredWaitHandle RegisterWaitForSingleObject( // throws RegisterWaitException - WaitHandle waitObject, - WaitOrTimerCallback callBack, - Object state, - uint millisecondsTimeOutInterval, - bool executeOnlyOnce // NOTE: we do not allow other options that allow the callback to be queued as an APC + WaitHandle waitObject, + WaitOrTimerCallback callBack, + Object state, + uint millisecondsTimeOutInterval, + bool executeOnlyOnce // NOTE: we do not allow other options that allow the callback to be queued as an APC ) { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; - return RegisterWaitForSingleObject(waitObject,callBack,state,millisecondsTimeOutInterval,executeOnlyOnce,ref stackMark,true); + return RegisterWaitForSingleObject(waitObject, callBack, state, millisecondsTimeOutInterval, executeOnlyOnce, ref stackMark, true); } [CLSCompliant(false)] - [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject( // throws RegisterWaitException - WaitHandle waitObject, - WaitOrTimerCallback callBack, - Object state, - uint millisecondsTimeOutInterval, - bool executeOnlyOnce // NOTE: we do not allow other options that allow the callback to be queued as an APC + WaitHandle waitObject, + WaitOrTimerCallback callBack, + Object state, + uint millisecondsTimeOutInterval, + bool executeOnlyOnce // NOTE: we do not allow other options that allow the callback to be queued as an APC ) { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; - return RegisterWaitForSingleObject(waitObject,callBack,state,millisecondsTimeOutInterval,executeOnlyOnce,ref stackMark,false); + return RegisterWaitForSingleObject(waitObject, callBack, state, millisecondsTimeOutInterval, executeOnlyOnce, ref stackMark, false); } private static RegisteredWaitHandle RegisterWaitForSingleObject( // throws RegisterWaitException - WaitHandle waitObject, - WaitOrTimerCallback callBack, - Object state, - uint millisecondsTimeOutInterval, - bool executeOnlyOnce, // NOTE: we do not allow other options that allow the callback to be queued as an APC + WaitHandle waitObject, + WaitOrTimerCallback callBack, + Object state, + uint millisecondsTimeOutInterval, + bool executeOnlyOnce, // NOTE: we do not allow other options that allow the callback to be queued as an APC ref StackCrawlMark stackMark, - bool compressStack + bool compressStack ) { RegisteredWaitHandle registeredWaitHandle = new RegisteredWaitHandle(); @@ -1160,7 +1158,7 @@ namespace System.Threading // this could occur if callback were to fire before SetWaitObject does its addref registeredWaitHandle.SetWaitObject(waitObject); IntPtr nativeRegisteredWaitHandle = RegisterWaitForSingleObjectNative(waitObject, - state, + state, millisecondsTimeOutInterval, executeOnlyOnce, registeredWaitHandle, @@ -1176,104 +1174,104 @@ namespace System.Threading } - [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod public static RegisteredWaitHandle RegisterWaitForSingleObject( // throws RegisterWaitException - WaitHandle waitObject, - WaitOrTimerCallback callBack, - Object state, - int millisecondsTimeOutInterval, - bool executeOnlyOnce // NOTE: we do not allow other options that allow the callback to be queued as an APC + WaitHandle waitObject, + WaitOrTimerCallback callBack, + Object state, + int millisecondsTimeOutInterval, + bool executeOnlyOnce // NOTE: we do not allow other options that allow the callback to be queued as an APC ) { if (millisecondsTimeOutInterval < -1) - throw new ArgumentOutOfRangeException(nameof(millisecondsTimeOutInterval), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); + throw new ArgumentOutOfRangeException(nameof(millisecondsTimeOutInterval), SR.ArgumentOutOfRange_NeedNonNegOrNegative1); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; - return RegisterWaitForSingleObject(waitObject,callBack,state,(UInt32)millisecondsTimeOutInterval,executeOnlyOnce,ref stackMark,true); + return RegisterWaitForSingleObject(waitObject, callBack, state, (UInt32)millisecondsTimeOutInterval, executeOnlyOnce, ref stackMark, true); } - [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject( // throws RegisterWaitException - WaitHandle waitObject, - WaitOrTimerCallback callBack, - Object state, - int millisecondsTimeOutInterval, - bool executeOnlyOnce // NOTE: we do not allow other options that allow the callback to be queued as an APC + WaitHandle waitObject, + WaitOrTimerCallback callBack, + Object state, + int millisecondsTimeOutInterval, + bool executeOnlyOnce // NOTE: we do not allow other options that allow the callback to be queued as an APC ) { if (millisecondsTimeOutInterval < -1) - throw new ArgumentOutOfRangeException(nameof(millisecondsTimeOutInterval), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); + throw new ArgumentOutOfRangeException(nameof(millisecondsTimeOutInterval), SR.ArgumentOutOfRange_NeedNonNegOrNegative1); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; - return RegisterWaitForSingleObject(waitObject,callBack,state,(UInt32)millisecondsTimeOutInterval,executeOnlyOnce,ref stackMark,false); + return RegisterWaitForSingleObject(waitObject, callBack, state, (UInt32)millisecondsTimeOutInterval, executeOnlyOnce, ref stackMark, false); } - [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod public static RegisteredWaitHandle RegisterWaitForSingleObject( // throws RegisterWaitException - WaitHandle waitObject, + WaitHandle waitObject, WaitOrTimerCallback callBack, - Object state, - long millisecondsTimeOutInterval, - bool executeOnlyOnce // NOTE: we do not allow other options that allow the callback to be queued as an APC + Object state, + long millisecondsTimeOutInterval, + bool executeOnlyOnce // NOTE: we do not allow other options that allow the callback to be queued as an APC ) { if (millisecondsTimeOutInterval < -1) - throw new ArgumentOutOfRangeException(nameof(millisecondsTimeOutInterval), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); + throw new ArgumentOutOfRangeException(nameof(millisecondsTimeOutInterval), SR.ArgumentOutOfRange_NeedNonNegOrNegative1); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; - return RegisterWaitForSingleObject(waitObject,callBack,state,(UInt32)millisecondsTimeOutInterval,executeOnlyOnce,ref stackMark,true); + return RegisterWaitForSingleObject(waitObject, callBack, state, (UInt32)millisecondsTimeOutInterval, executeOnlyOnce, ref stackMark, true); } - [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject( // throws RegisterWaitException - WaitHandle waitObject, + WaitHandle waitObject, WaitOrTimerCallback callBack, - Object state, - long millisecondsTimeOutInterval, - bool executeOnlyOnce // NOTE: we do not allow other options that allow the callback to be queued as an APC + Object state, + long millisecondsTimeOutInterval, + bool executeOnlyOnce // NOTE: we do not allow other options that allow the callback to be queued as an APC ) { if (millisecondsTimeOutInterval < -1) - throw new ArgumentOutOfRangeException(nameof(millisecondsTimeOutInterval), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); + throw new ArgumentOutOfRangeException(nameof(millisecondsTimeOutInterval), SR.ArgumentOutOfRange_NeedNonNegOrNegative1); Contract.EndContractBlock(); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; - return RegisterWaitForSingleObject(waitObject,callBack,state,(UInt32)millisecondsTimeOutInterval,executeOnlyOnce,ref stackMark,false); + return RegisterWaitForSingleObject(waitObject, callBack, state, (UInt32)millisecondsTimeOutInterval, executeOnlyOnce, ref stackMark, false); } - [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod public static RegisteredWaitHandle RegisterWaitForSingleObject( - WaitHandle waitObject, - WaitOrTimerCallback callBack, - Object state, - TimeSpan timeout, - bool executeOnlyOnce + WaitHandle waitObject, + WaitOrTimerCallback callBack, + Object state, + TimeSpan timeout, + bool executeOnlyOnce ) { long tm = (long)timeout.TotalMilliseconds; if (tm < -1) - throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); - if (tm > (long) Int32.MaxValue) - throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_LessEqualToIntegerMaxVal")); + throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1); + if (tm > (long)Int32.MaxValue) + throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_LessEqualToIntegerMaxVal); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; - return RegisterWaitForSingleObject(waitObject,callBack,state,(UInt32)tm,executeOnlyOnce,ref stackMark,true); + return RegisterWaitForSingleObject(waitObject, callBack, state, (UInt32)tm, executeOnlyOnce, ref stackMark, true); } - [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject( - WaitHandle waitObject, - WaitOrTimerCallback callBack, - Object state, - TimeSpan timeout, - bool executeOnlyOnce + WaitHandle waitObject, + WaitOrTimerCallback callBack, + Object state, + TimeSpan timeout, + bool executeOnlyOnce ) { long tm = (long)timeout.TotalMilliseconds; if (tm < -1) - throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); - if (tm > (long) Int32.MaxValue) - throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_LessEqualToIntegerMaxVal")); + throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1); + if (tm > (long)Int32.MaxValue) + throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_LessEqualToIntegerMaxVal); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; - return RegisterWaitForSingleObject(waitObject,callBack,state,(UInt32)tm,executeOnlyOnce,ref stackMark,false); + return RegisterWaitForSingleObject(waitObject, callBack, state, (UInt32)tm, executeOnlyOnce, ref stackMark, false); } public static bool QueueUserWorkItem(WaitCallback callBack) => @@ -1428,7 +1426,7 @@ namespace System.Threading EnsureVMInitializedCore(); // separate out to help with inlining } } - + private static void EnsureVMInitializedCore() { ThreadPool.InitializeVMTp(ref ThreadPoolGlobals.enableWorkerTracking); @@ -1436,7 +1434,7 @@ namespace System.Threading } // Native methods: - + [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern bool SetMinThreadsNative(int workerThreads, int completionPortThreads); @@ -1468,22 +1466,19 @@ namespace System.Threading [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern void NotifyWorkItemProgressNative(); - [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern bool IsThreadPoolHosted(); - [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [SuppressUnmanagedCodeSecurity] private static extern void InitializeVMTp(ref bool enableWorkerTracking); [MethodImplAttribute(MethodImplOptions.InternalCall)] - private static extern IntPtr RegisterWaitForSingleObjectNative( - WaitHandle waitHandle, - Object state, - uint timeOutInterval, - bool executeOnlyOnce, - RegisteredWaitHandle registeredWaitHandle, - ref StackCrawlMark stackMark, - bool compressStack + private static extern IntPtr RegisterWaitForSingleObjectNative( + WaitHandle waitHandle, + Object state, + uint timeOutInterval, + bool executeOnlyOnce, + RegisteredWaitHandle registeredWaitHandle, + ref StackCrawlMark stackMark, + bool compressStack ); @@ -1497,15 +1492,17 @@ namespace System.Threading { if (osHandle == null) throw new ArgumentNullException(nameof(osHandle)); - + bool ret = false; bool mustReleaseSafeHandle = false; RuntimeHelpers.PrepareConstrainedRegions(); - try { + try + { osHandle.DangerousAddRef(ref mustReleaseSafeHandle); ret = BindIOCompletionCallbackNative(osHandle.DangerousGetHandle()); } - finally { + finally + { if (mustReleaseSafeHandle) osHandle.DangerousRelease(); } |