diff --git a/src/mscorlib/src/System/Threading/ThreadPool.cs b/src/mscorlib/src/System/Threading/ThreadPool.cs index f9d8e7da98e0..bf700601cd03 100644 --- a/src/mscorlib/src/System/Threading/ThreadPool.cs +++ b/src/mscorlib/src/System/Threading/ThreadPool.cs @@ -46,21 +46,25 @@ internal static class ThreadPoolGlobals { //Per-appDomain quantum (in ms) for which the thread keeps processing //requests in the current domain. - public static uint tpQuantum = 30U; + public static uint tpQuantum; - public static int processorCount = Environment.ProcessorCount; + public static int processorCount; - public static bool tpHosted = ThreadPool.IsThreadPoolHosted(); + public static bool tpHosted; public static volatile bool vmTpInitialized; public static bool enableWorkerTracking; [SecurityCritical] - public static ThreadPoolWorkQueue workQueue = new ThreadPoolWorkQueue(); + public static ThreadPoolWorkQueue workQueue; - [System.Security.SecuritySafeCritical] // static constructors should be safe to call - static ThreadPoolGlobals() + [SecurityCritical] + internal static void Initialize() { + tpQuantum = 30U; + processorCount = Environment.ProcessorCount; + tpHosted = ThreadPool.IsThreadPoolHosted(); + workQueue = new ThreadPoolWorkQueue(); } } @@ -1168,9 +1172,6 @@ internal interface IThreadPoolWorkItem internal sealed class QueueUserWorkItemCallback : IThreadPoolWorkItem { - [System.Security.SecuritySafeCritical] - static QueueUserWorkItemCallback() {} - private WaitCallback callback; private ExecutionContext context; private Object state; @@ -1197,6 +1198,7 @@ void MarkExecuted(bool aborted) [SecurityCritical] internal QueueUserWorkItemCallback(WaitCallback waitCallback, Object stateObj, ExecutionContext ec) { + Contract.Assert(waitCallback != null, "Null callback passed to QueueUserWorkItemCallback!"); callback = waitCallback; state = stateObj; context = ec; @@ -1232,23 +1234,23 @@ void IThreadPoolWorkItem.MarkAborted(ThreadAbortException tae) } [System.Security.SecurityCritical] - static internal ContextCallback ccb = new ContextCallback(WaitCallback_Context); + static internal ContextCallback ccb; [System.Security.SecurityCritical] - static private void WaitCallback_Context(Object state) + static internal void Initialize() { - QueueUserWorkItemCallback obj = (QueueUserWorkItemCallback)state; - WaitCallback wc = obj.callback as WaitCallback; - Contract.Assert(null != wc); - wc(obj.state); + ccb = (state) => { ((QueueUserWorkItemCallback)state).WaitCallback_Context(); }; + } + + [System.Security.SecurityCritical] + private void WaitCallback_Context() + { + callback(state); } } internal sealed class QueueUserWorkItemCallbackDefaultContext : IThreadPoolWorkItem { - [System.Security.SecuritySafeCritical] - static QueueUserWorkItemCallbackDefaultContext() { } - private WaitCallback callback; private Object state; @@ -1274,6 +1276,7 @@ void MarkExecuted(bool aborted) [SecurityCritical] internal QueueUserWorkItemCallbackDefaultContext(WaitCallback waitCallback, Object stateObj) { + Contract.Assert(waitCallback != null, "Null callback passed to QueueUserWorkItemCallbackDefaultContext!"); callback = waitCallback; state = stateObj; } @@ -1298,35 +1301,43 @@ void IThreadPoolWorkItem.MarkAborted(ThreadAbortException tae) } [System.Security.SecurityCritical] - static internal ContextCallback ccb = new ContextCallback(WaitCallback_Context); + static internal ContextCallback ccb; [System.Security.SecurityCritical] - static private void WaitCallback_Context(Object state) + static internal void Initialize() { - QueueUserWorkItemCallbackDefaultContext obj = (QueueUserWorkItemCallbackDefaultContext)state; - WaitCallback wc = obj.callback as WaitCallback; - Contract.Assert(null != wc); - obj.callback = null; - wc(obj.state); + ccb = (state) => { ((QueueUserWorkItemCallbackDefaultContext)state).WaitCallback_Context(); }; + } + + [System.Security.SecurityCritical] + private void WaitCallback_Context() + { + callback(state); } } internal class _ThreadPoolWaitOrTimerCallback { - [System.Security.SecuritySafeCritical] - static _ThreadPoolWaitOrTimerCallback() {} - WaitOrTimerCallback _waitOrTimerCallback; ExecutionContext _executionContext; Object _state; [System.Security.SecurityCritical] - static private ContextCallback _ccbt = new ContextCallback(WaitOrTimerCallback_Context_t); + static private ContextCallback _ccbt; [System.Security.SecurityCritical] - static private ContextCallback _ccbf = new ContextCallback(WaitOrTimerCallback_Context_f); + static private ContextCallback _ccbf; + + [System.Security.SecurityCritical] + static internal void Initialize() + { + _ccbt = (state) => { ((_ThreadPoolWaitOrTimerCallback)state).WaitOrTimerCallback_Context(true); }; + _ccbf = (state) => { ((_ThreadPoolWaitOrTimerCallback)state).WaitOrTimerCallback_Context(false); }; + } [System.Security.SecurityCritical] // auto-generated internal _ThreadPoolWaitOrTimerCallback(WaitOrTimerCallback waitOrTimerCallback, Object state, bool compressStack, ref StackCrawlMark stackMark) { + Contract.Assert(waitOrTimerCallback != null, "Null callback passed to _ThreadPoolWaitOrTimerCallback!"); + _waitOrTimerCallback = waitOrTimerCallback; _state = state; @@ -1338,23 +1349,10 @@ internal _ThreadPoolWaitOrTimerCallback(WaitOrTimerCallback waitOrTimerCallback, ExecutionContext.CaptureOptions.IgnoreSyncCtx | ExecutionContext.CaptureOptions.OptimizeDefaultCase); } } - - [System.Security.SecurityCritical] - static private void WaitOrTimerCallback_Context_t(Object state) - { - WaitOrTimerCallback_Context(state, true); - } - - [System.Security.SecurityCritical] - static private void WaitOrTimerCallback_Context_f(Object state) - { - WaitOrTimerCallback_Context(state, false); - } - static private void WaitOrTimerCallback_Context(Object state, bool timedOut) + private void WaitOrTimerCallback_Context(bool timedOut) { - _ThreadPoolWaitOrTimerCallback helper = (_ThreadPoolWaitOrTimerCallback)state; - helper._waitOrTimerCallback(helper._state, timedOut); + _waitOrTimerCallback(_state, timedOut); } // call back helper @@ -1845,6 +1843,12 @@ private static void EnsureVMInitialized() if (!ThreadPoolGlobals.vmTpInitialized) { ThreadPool.InitializeVMTp(ref ThreadPoolGlobals.enableWorkerTracking); + + ThreadPoolGlobals.Initialize(); + QueueUserWorkItemCallback.Initialize(); + QueueUserWorkItemCallbackDefaultContext.Initialize(); + _ThreadPoolWaitOrTimerCallback.Initialize(); + ThreadPoolGlobals.vmTpInitialized = true; } } @@ -1882,8 +1886,7 @@ private static void EnsureVMInitialized() [System.Security.SecuritySafeCritical] internal static void NotifyWorkItemProgress() { - if (!ThreadPoolGlobals.vmTpInitialized) - ThreadPool.InitializeVMTp(ref ThreadPoolGlobals.enableWorkerTracking); + EnsureVMInitialized(); NotifyWorkItemProgressNative(); }