Code:
/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / clr / src / BCL / System / Threading / ThreadPool.cs / 4 / ThreadPool.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== /*============================================================================== ** ** Class: ThreadPool ** ** ** Purpose: Class for creating and managing a threadpool ** ** =============================================================================*/ /* * Below you'll notice two sets of APIs that are separated by the * use of 'Unsafe' in their names. The unsafe versions are called * that because they do not propagate the calling stack onto the * worker thread. This allows code to lose the calling stack and * thereby elevate its security privileges. Note that this operation * is much akin to the combined ability to control security policy * and control security evidence. With these privileges, a person * can gain the right to load assemblies that are fully trusted which * then assert full trust and can call any code they want regardless * of the previous stack information. */ namespace System.Threading { using System.Security; using System.Threading; using System.Runtime.Remoting; using System.Security.Permissions; using System; using Microsoft.Win32; using System.Runtime.CompilerServices; using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; internal static class ThreadPoolGlobals { //Per-appDomain quantum (in ms) for which the thread keeps processing //requests in the current domain. public static uint tpQuantum = 2; public static int tpWarmupCount = GetProcessorCount() * 2; public static bool tpHosted = ThreadPool.IsThreadPoolHosted(); public static bool vmTpInitialized; public static ThreadPoolRequestQueue tpQueue = new ThreadPoolRequestQueue(); [EnvironmentPermissionAttribute(SecurityAction.Assert, Read="NUMBER_OF_PROCESSORS")] private static int GetProcessorCount() { return Environment.ProcessorCount; } } internal sealed class ThreadPoolRequestQueue { private _ThreadPoolWaitCallback tpHead; private _ThreadPoolWaitCallback tpTail; //The dummy object used to synchronize thread pool queue access. private Object tpSync; //The number of work-items in thread pool queue. private uint tpCount; public ThreadPoolRequestQueue() { tpSync = new Object(); } public uint EnQueue(_ThreadPoolWaitCallback tpcallBack) { uint count = 0; bool tookLock = false; bool setNativeTpEvent = false; RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { RuntimeHelpers.PrepareConstrainedRegions(); try { Monitor.Enter(tpSync); tookLock = true; } catch(Exception) { } if (tookLock) { if(tpCount == 0) { //Indicate to the VM that there is work in this domain. //Its important to synchronize this notice, otherwise //the VM may not schedule any thread in this domain. setNativeTpEvent = ThreadPool.SetAppDomainRequestActive(); } tpCount++; count = tpCount; if(tpHead == null) { tpHead = tpcallBack; tpTail = tpcallBack; } else { tpTail._next = tpcallBack; tpTail = tpcallBack; } Monitor.Exit(tpSync); if(setNativeTpEvent) { ThreadPool.SetNativeTpEvent(); } } } return count; } public _ThreadPoolWaitCallback DeQueue() { bool tookLock = false; _ThreadPoolWaitCallback tpWaitCallBack = null; RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { RuntimeHelpers.PrepareConstrainedRegions(); try { Monitor.Enter(tpSync); tookLock = true; } catch(Exception) { } if (tookLock) { _ThreadPoolWaitCallback head = tpHead; if ( head != null) { tpWaitCallBack = head; tpHead = head._next; tpCount--; if(tpCount == 0) { BCLDebug.Assert(tpHead == null,"TP Queue head expected to be null"); tpTail = null; //Indicate to the VM that there is no work in this //domain. Its important to synchronize this notice, //otherwise the VM may keep calling the Managed //callbacks endlessly. ThreadPool.ClearAppDomainRequestActive(); } } Monitor.Exit(tpSync); } } return tpWaitCallBack; } public uint GetQueueCount() { return tpCount; } } internal sealed class RegisteredWaitHandleSafe : CriticalFinalizerObject { private static readonly IntPtr InvalidHandle = Win32Native.INVALID_HANDLE_VALUE; private IntPtr registeredWaitHandle; private WaitHandle m_internalWaitObject; private bool bReleaseNeeded = false; private int m_lock = 0; internal RegisteredWaitHandleSafe() { registeredWaitHandle = InvalidHandle; } internal IntPtr GetHandle() { return registeredWaitHandle; } internal void SetHandle(IntPtr handle) { registeredWaitHandle = handle; } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] internal void SetWaitObject(WaitHandle waitObject) { // needed for DangerousAddRef RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { m_internalWaitObject = waitObject; if (waitObject != null) { m_internalWaitObject.SafeWaitHandle.DangerousAddRef(ref bReleaseNeeded); } } } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] internal bool Unregister( WaitHandle waitObject // object to be notified when all callbacks to delegates have completed ) { bool result = false; // needed for DangerousRelease RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { // 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 { if (Interlocked.CompareExchange(ref m_lock, 1, 0) == 0) { bLockTaken = true; try { if (ValidHandle()) { result = UnregisterWaitNative(GetHandle(), waitObject == null ? null : waitObject.SafeWaitHandle); if (result == true) { if (bReleaseNeeded) { m_internalWaitObject.SafeWaitHandle.DangerousRelease(); bReleaseNeeded = false; } // if result not true don't release/suppress here so finalizer can make another attempt SetHandle(InvalidHandle); m_internalWaitObject = null; GC.SuppressFinalize(this); } } } finally { m_lock = 0; } } Thread.SpinWait(1); // yield to processor } while (!bLockTaken); } return result; } private bool ValidHandle() { return (registeredWaitHandle != InvalidHandle && registeredWaitHandle != IntPtr.Zero); } ~RegisteredWaitHandleSafe() { // if the app has already unregistered the wait, there is nothing to cleanup // we can detect this by checking the handle. Normally, there is no race here // so no need to protect reading of handle. However, if this object gets // resurrected and then someone does an unregister, it would introduce a race // PrepareConstrainedRegions call not needed since finalizer already in Cer // lock(this) cannot be used reliably even in Cer since thin lock could be // promoted to syncblock and that is not a guaranteed operation bool bLockTaken = false; do { if (Interlocked.CompareExchange(ref m_lock, 1, 0) == 0) { bLockTaken = true; try { if (ValidHandle()) { WaitHandleCleanupNative(registeredWaitHandle); if (bReleaseNeeded) { m_internalWaitObject.SafeWaitHandle.DangerousRelease(); bReleaseNeeded = false; } SetHandle(InvalidHandle); m_internalWaitObject = null; } } finally { m_lock = 0; } } Thread.SpinWait(1); // yield to processor } while (!bLockTaken); } [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern void WaitHandleCleanupNative(IntPtr handle); [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern bool UnregisterWaitNative(IntPtr handle, SafeHandle waitObject); } [System.Runtime.InteropServices.ComVisible(true)] public sealed class RegisteredWaitHandle : MarshalByRefObject { private RegisteredWaitHandleSafe internalRegisteredWait; internal RegisteredWaitHandle() { internalRegisteredWait = new RegisteredWaitHandleSafe(); } internal void SetHandle(IntPtr handle) { internalRegisteredWait.SetHandle(handle); } internal void SetWaitObject(WaitHandle waitObject) { internalRegisteredWait.SetWaitObject(waitObject); } [System.Runtime.InteropServices.ComVisible(true)] // 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 ) { return internalRegisteredWait.Unregister(waitObject); } } [System.Runtime.InteropServices.ComVisible(true)] public delegate void WaitCallback(Object state); [System.Runtime.InteropServices.ComVisible(true)] public delegate void WaitOrTimerCallback(Object state, bool timedOut); // signalled or timed out internal class _ThreadPoolWaitCallback { WaitCallback _waitCallback; ExecutionContext _executionContext; Object _state; //ThreadPoolWaitCallBack is the unit of thread pool work, and is //chained together. The _next field is the link. This field should be //accessible to the Thread pool queue in order to reduce number of //object allocations as this is on a perf-critical path. protected internal _ThreadPoolWaitCallback _next; static internal ContextCallback _ccb = new ContextCallback(WaitCallback_Context); static internal void WaitCallback_Context(Object state) { _ThreadPoolWaitCallback obj = (_ThreadPoolWaitCallback)state; obj._waitCallback(obj._state); } internal _ThreadPoolWaitCallback(WaitCallback waitCallback, Object state, bool compressStack, ref StackCrawlMark stackMark) { _waitCallback = waitCallback; _state = state; if (compressStack && !ExecutionContext.IsFlowSuppressed()) { // clone the exection context _executionContext = ExecutionContext.Capture(ref stackMark); ExecutionContext.ClearSyncContext(_executionContext); } } // call back helper // This function dispatches requests to the user-callbacks. The // work-items are fetched from the per-appdomain queue in a loop until // either there is no more work or the quantum has expired. The quantum // is enforced to maintain fairness among appdomains. static internal void PerformWaitCallback(Object state) { int totTime=0; _ThreadPoolWaitCallback tpWaitCallBack = null; int startTime = Environment.TickCount; do { tpWaitCallBack = ThreadPoolGlobals.tpQueue.DeQueue(); if ( tpWaitCallBack == null) { break; } // This call in the VM updates queue counts, number of // completed requests, etc. More importantly, it also // resets thread state like CriticalRegionCount, priority etc. // ThreadPool.CompleteThreadPoolRequest(ThreadPoolGlobals.tpQueue.GetQueueCount()); PerformWaitCallbackInternal(tpWaitCallBack); int endTime = Environment.TickCount; totTime = (endTime - startTime); // Check to see if quantum has expired. if(totTime > ThreadPoolGlobals.tpQuantum) { if(ThreadPool.ShouldReturnToVm()) { break; } } } while (true); } static internal void PerformWaitCallbackInternal(_ThreadPoolWaitCallback tpWaitCallBack) { // call directly if it is an unsafe call OR EC flow is suppressed if (tpWaitCallBack._executionContext == null) { WaitCallback callback = tpWaitCallBack._waitCallback; callback(tpWaitCallBack._state); } else { ExecutionContext.Run(tpWaitCallBack._executionContext, _ccb, tpWaitCallBack); } } }; internal class _ThreadPoolWaitOrTimerCallback { WaitOrTimerCallback _waitOrTimerCallback; ExecutionContext _executionContext; Object _state; static private ContextCallback _ccbt = new ContextCallback(WaitOrTimerCallback_Context_t); static private ContextCallback _ccbf = new ContextCallback(WaitOrTimerCallback_Context_f); internal _ThreadPoolWaitOrTimerCallback(WaitOrTimerCallback waitOrTimerCallback, Object state, bool compressStack, ref StackCrawlMark stackMark) { _waitOrTimerCallback = waitOrTimerCallback; _state = state; if (compressStack && !ExecutionContext.IsFlowSuppressed()) { // capture the exection context _executionContext = ExecutionContext.Capture(ref stackMark); ExecutionContext.ClearSyncContext(_executionContext); } } static private void WaitOrTimerCallback_Context_t(Object state) { WaitOrTimerCallback_Context(state, true); } static private void WaitOrTimerCallback_Context_f(Object state) { WaitOrTimerCallback_Context(state, false); } static private void WaitOrTimerCallback_Context(Object state, bool timedOut) { _ThreadPoolWaitOrTimerCallback helper = (_ThreadPoolWaitOrTimerCallback)state; helper._waitOrTimerCallback(helper._state, timedOut); } // call back helper static internal void PerformWaitOrTimerCallback(Object state, bool timedOut) { _ThreadPoolWaitOrTimerCallback helper = (_ThreadPoolWaitOrTimerCallback)state; BCLDebug.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) { WaitOrTimerCallback callback = helper._waitOrTimerCallback; callback(helper._state, timedOut); } else { if (timedOut) ExecutionContext.Run(helper._executionContext.CreateCopy(), _ccbt, helper); else ExecutionContext.Run(helper._executionContext.CreateCopy(), _ccbf, helper); } } }; [CLSCompliant(false)] [System.Runtime.InteropServices.ComVisible(true)] unsafe public delegate void IOCompletionCallback(uint errorCode, // Error code uint numBytes, // No. of bytes transferred NativeOverlapped* pOVERLAP // ptr to OVERLAP structure ); [HostProtection(Synchronization=true, ExternalThreading=true)] public static class ThreadPool { [SecurityPermissionAttribute(SecurityAction.Demand, ControlThread = true)] public static bool SetMaxThreads(int workerThreads, int completionPortThreads) { return SetMaxThreadsNative(workerThreads, completionPortThreads); } public static void GetMaxThreads(out int workerThreads, out int completionPortThreads) { GetMaxThreadsNative(out workerThreads, out completionPortThreads); } [SecurityPermissionAttribute(SecurityAction.Demand, ControlThread = true)] public static bool SetMinThreads(int workerThreads, int completionPortThreads) { return SetMinThreadsNative(workerThreads, completionPortThreads); } public static void GetMinThreads(out int workerThreads, out int completionPortThreads) { GetMinThreadsNative(out workerThreads, out completionPortThreads); } public static void GetAvailableThreads(out int workerThreads, out int completionPortThreads) { GetAvailableThreadsNative(out workerThreads, out completionPortThreads); } [CLSCompliant(false)] 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 ) { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; return RegisterWaitForSingleObject(waitObject,callBack,state,millisecondsTimeOutInterval,executeOnlyOnce,ref stackMark,true); } [CLSCompliant(false), SecurityPermissionAttribute( SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.ControlEvidence | SecurityPermissionFlag.ControlPolicy)] 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 ) { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; 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 ref StackCrawlMark stackMark, bool compressStack ) { if (RemotingServices.IsTransparentProxy(waitObject)) throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_WaitOnTransparentProxy")); RegisteredWaitHandle registeredWaitHandle = new RegisteredWaitHandle(); if (callBack != null) { _ThreadPoolWaitOrTimerCallback callBackHelper = new _ThreadPoolWaitOrTimerCallback(callBack, state, compressStack, ref stackMark); state = (Object)callBackHelper; // call SetWaitObject before native call so that waitObject won't be closed before threadpoolmgr registration // this could occur if callback were to fire before SetWaitObject does its addref registeredWaitHandle.SetWaitObject(waitObject); IntPtr nativeRegisteredWaitHandle = RegisterWaitForSingleObjectNative(waitObject, state, millisecondsTimeOutInterval, executeOnlyOnce, registeredWaitHandle, ref stackMark, compressStack); registeredWaitHandle.SetHandle(nativeRegisteredWaitHandle); } else { throw new ArgumentNullException("WaitOrTimerCallback"); } return registeredWaitHandle; } 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 ) { if (millisecondsTimeOutInterval < -1) throw new ArgumentOutOfRangeException("millisecondsTimeOutInterval", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; return RegisterWaitForSingleObject(waitObject,callBack,state,(UInt32)millisecondsTimeOutInterval,executeOnlyOnce,ref stackMark,true); } [SecurityPermissionAttribute( SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.ControlEvidence | SecurityPermissionFlag.ControlPolicy)] 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 ) { if (millisecondsTimeOutInterval < -1) throw new ArgumentOutOfRangeException("millisecondsTimeOutInterval", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; return RegisterWaitForSingleObject(waitObject,callBack,state,(UInt32)millisecondsTimeOutInterval,executeOnlyOnce,ref stackMark,false); } public static RegisteredWaitHandle RegisterWaitForSingleObject( // throws RegisterWaitException 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 ) { if (millisecondsTimeOutInterval < -1) throw new ArgumentOutOfRangeException("millisecondsTimeOutInterval", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; return RegisterWaitForSingleObject(waitObject,callBack,state,(UInt32)millisecondsTimeOutInterval,executeOnlyOnce,ref stackMark,true); } [SecurityPermissionAttribute( SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.ControlEvidence | SecurityPermissionFlag.ControlPolicy)] public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject( // throws RegisterWaitException 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 ) { if (millisecondsTimeOutInterval < -1) throw new ArgumentOutOfRangeException("millisecondsTimeOutInterval", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; return RegisterWaitForSingleObject(waitObject,callBack,state,(UInt32)millisecondsTimeOutInterval,executeOnlyOnce,ref stackMark,false); } public static RegisteredWaitHandle RegisterWaitForSingleObject( WaitHandle waitObject, WaitOrTimerCallback callBack, Object state, TimeSpan timeout, bool executeOnlyOnce ) { long tm = (long)timeout.TotalMilliseconds; if (tm < -1) throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); if (tm > (long) Int32.MaxValue) throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_LessEqualToIntegerMaxVal")); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; return RegisterWaitForSingleObject(waitObject,callBack,state,(UInt32)tm,executeOnlyOnce,ref stackMark,true); } [SecurityPermissionAttribute( SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.ControlEvidence | SecurityPermissionFlag.ControlPolicy)] public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject( WaitHandle waitObject, WaitOrTimerCallback callBack, Object state, TimeSpan timeout, bool executeOnlyOnce ) { long tm = (long)timeout.TotalMilliseconds; if (tm < -1) throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); if (tm > (long) Int32.MaxValue) throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_LessEqualToIntegerMaxVal")); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; return RegisterWaitForSingleObject(waitObject,callBack,state,(UInt32)tm,executeOnlyOnce,ref stackMark,false); } public static bool QueueUserWorkItem( WaitCallback callBack, // NOTE: we do not expose options that allow the callback to be queued as an APC Object state ) { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; return QueueUserWorkItemHelper(callBack,state,ref stackMark,true); } public static bool QueueUserWorkItem( WaitCallback callBack // NOTE: we do not expose options that allow the callback to be queued as an APC ) { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; return QueueUserWorkItemHelper(callBack,null,ref stackMark,true); } [SecurityPermissionAttribute( SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.ControlEvidence | SecurityPermissionFlag.ControlPolicy)] public static bool UnsafeQueueUserWorkItem( WaitCallback callBack, // NOTE: we do not expose options that allow the callback to be queued as an APC Object state ) { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; return QueueUserWorkItemHelper(callBack,state,ref stackMark,false); } //ThreadPool has per-appdomain managed queue of work-items. The VM is //responsible for just scheduling threads into appdomains. After that //work-items are dispatched from the managed queue. private static bool QueueUserWorkItemHelper(WaitCallback callBack, Object state, ref StackCrawlMark stackMark, bool compressStack ) { bool success = true; if (callBack != null) { //The thread pool maintains a per-appdomain managed work queue. //New thread pool entries are added in the managed queue. //The VM is responsible for the actual growing/shrinking of //threads. _ThreadPoolWaitCallback tpcallBack = new _ThreadPoolWaitCallback(callBack, state, compressStack, ref stackMark); if(!ThreadPoolGlobals.vmTpInitialized) { ThreadPool.InitializeVMTp(); ThreadPoolGlobals.vmTpInitialized = true; } uint queueCount; queueCount = ThreadPoolGlobals.tpQueue.EnQueue(tpcallBack); //Make sure the unmanaged thread pool creates some threads //before accepting requests in the managed queue. if( (ThreadPoolGlobals.tpHosted) || (queueCount < ThreadPoolGlobals.tpWarmupCount)) { success = AdjustThreadsInPool(ThreadPoolGlobals.tpQueue.GetQueueCount()); } else { UpdateNativeTpCount(ThreadPoolGlobals.tpQueue.GetQueueCount()); } return success; } else { throw new ArgumentNullException("WaitCallback"); } } [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern bool AdjustThreadsInPool(uint QueueLength); [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern void UpdateNativeTpCount(uint QueueLength); [MethodImplAttribute(MethodImplOptions.InternalCall)] unsafe private static extern bool PostQueuedCompletionStatus(NativeOverlapped* overlapped); [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern void InitializeVMTp(); [CLSCompliant(false)] [SecurityPermissionAttribute( SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.ControlEvidence | SecurityPermissionFlag.ControlPolicy)] unsafe public static bool UnsafeQueueNativeOverlapped(NativeOverlapped* overlapped) { return PostQueuedCompletionStatus(overlapped); } // Native methods: [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern bool SetMinThreadsNative(int workerThreads, int completionPortThreads); [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern bool SetMaxThreadsNative(int workerThreads, int completionPortThreads); [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern void GetMinThreadsNative(out int workerThreads, out int completionPortThreads); [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern void GetMaxThreadsNative(out int workerThreads, out int completionPortThreads); [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern void GetAvailableThreadsNative(out int workerThreads, out int completionPortThreads); [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern void CompleteThreadPoolRequest(uint QueueLength); [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern bool ShouldReturnToVm(); [MethodImplAttribute(MethodImplOptions.InternalCall)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] internal static extern bool SetAppDomainRequestActive(); [MethodImplAttribute(MethodImplOptions.InternalCall)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] internal static extern void ClearAppDomainRequestActive(); [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern bool IsThreadPoolHosted(); [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern void SetNativeTpEvent(); [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern IntPtr RegisterWaitForSingleObjectNative( WaitHandle waitHandle, Object state, uint timeOutInterval, bool executeOnlyOnce, RegisteredWaitHandle registeredWaitHandle, ref StackCrawlMark stackMark, bool compressStack ); [Obsolete("ThreadPool.BindHandle(IntPtr) has been deprecated. Please use ThreadPool.BindHandle(SafeHandle) instead.", false)] [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] public static bool BindHandle( IntPtr osHandle ) { return BindIOCompletionCallbackNative(osHandle); } [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] public static bool BindHandle(SafeHandle osHandle) { if (osHandle == null) throw new ArgumentNullException("osHandle"); bool ret = false; bool mustReleaseSafeHandle = false; RuntimeHelpers.PrepareConstrainedRegions(); try { osHandle.DangerousAddRef(ref mustReleaseSafeHandle); ret = BindIOCompletionCallbackNative(osHandle.DangerousGetHandle()); } finally { if (mustReleaseSafeHandle) osHandle.DangerousRelease(); } return ret; } [MethodImplAttribute(MethodImplOptions.InternalCall)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] private static extern bool BindIOCompletionCallbackNative(IntPtr fileHandle); } }
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- RoleBoolean.cs
- XmlDocumentSerializer.cs
- AppDomainUnloadedException.cs
- WSSecurityTokenSerializer.cs
- WebPartEditorApplyVerb.cs
- CustomValidator.cs
- ObjectSerializerFactory.cs
- SqlTrackingQuery.cs
- CompiledRegexRunner.cs
- DetailsViewInsertedEventArgs.cs
- SettingsPropertyIsReadOnlyException.cs
- DbTransaction.cs
- DropTarget.cs
- WindowsStartMenu.cs
- CodeMethodReturnStatement.cs
- StringResourceManager.cs
- ToolStripDesignerUtils.cs
- DummyDataSource.cs
- Enum.cs
- WebBaseEventKeyComparer.cs
- HtmlInputPassword.cs
- WeakReferenceKey.cs
- AlternateView.cs
- EntityDataSourceChangingEventArgs.cs
- SettingsPropertyValueCollection.cs
- RSAPKCS1KeyExchangeFormatter.cs
- DownloadProgressEventArgs.cs
- XmlWellformedWriterHelpers.cs
- ProfessionalColorTable.cs
- TextEditorContextMenu.cs
- DataGridViewButtonColumn.cs
- ExpressionConverter.cs
- MsmqIntegrationProcessProtocolHandler.cs
- SimpleWorkerRequest.cs
- Oid.cs
- BamlLocalizableResourceKey.cs
- WindowsGraphics2.cs
- EventItfInfo.cs
- OLEDB_Util.cs
- UserControlCodeDomTreeGenerator.cs
- WindowsFormsHelpers.cs
- OutOfProcStateClientManager.cs
- Random.cs
- InvalidPrinterException.cs
- HttpCookiesSection.cs
- CharAnimationBase.cs
- DelimitedListTraceListener.cs
- Geometry3D.cs
- NameValuePair.cs
- CrossContextChannel.cs
- CommandDevice.cs
- TrackingServices.cs
- BitmapEffectDrawing.cs
- VSWCFServiceContractGenerator.cs
- CursorConverter.cs
- BufferAllocator.cs
- CounterCreationData.cs
- LocalizableAttribute.cs
- ToolStripLabel.cs
- WindowExtensionMethods.cs
- TableRowCollection.cs
- KnownBoxes.cs
- LiteralControl.cs
- NamedObject.cs
- AdRotator.cs
- Roles.cs
- Slider.cs
- PasswordRecovery.cs
- StylusEditingBehavior.cs
- LocationReferenceValue.cs
- ToolStripContainer.cs
- SqlBuilder.cs
- ByteAnimationBase.cs
- SchemaMerger.cs
- RichTextBoxConstants.cs
- KeyEventArgs.cs
- FormViewModeEventArgs.cs
- Selector.cs
- SelectorAutomationPeer.cs
- Hash.cs
- HtmlInputImage.cs
- ReflectionPermission.cs
- MethodMessage.cs
- EncryptedKey.cs
- CheckedListBox.cs
- DataGridViewTextBoxEditingControl.cs
- TextChangedEventArgs.cs
- ResourceWriter.cs
- UpdateManifestForBrowserApplication.cs
- QilExpression.cs
- XamlPathDataSerializer.cs
- GridViewDeletedEventArgs.cs
- ReflectEventDescriptor.cs
- XomlCompilerParameters.cs
- LocalizableAttribute.cs
- BaseCAMarshaler.cs
- CorrelationManager.cs
- ConfigurationStrings.cs
- StrokeCollection2.cs
- connectionpool.cs