Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / ndp / clr / src / BCL / System / Threading / Thread.cs / 1 / Thread.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== /*============================================================================== ** ** Class: Thread ** ** ** Purpose: Class for creating and managing a thread. ** ** =============================================================================*/ namespace System.Threading { using System.Threading; using System.Runtime.InteropServices; using System.Runtime.Remoting.Contexts; using System.Runtime.Remoting.Messaging; using System; using System.Diagnostics; using System.Security.Permissions; using System.Security.Principal; using System.Globalization; using System.Collections.Generic; using System.Runtime.Serialization; using System.Runtime.CompilerServices; using System.Runtime.ConstrainedExecution; using System.Security; using System.Runtime.Versioning; internal delegate Object InternalCrossContextDelegate(Object[] args); internal class ThreadHelper { Delegate _start; Object _startArg = null; ExecutionContext _executionContext = null; internal ThreadHelper(Delegate start) { _start = start; } internal void SetExecutionContextHelper(ExecutionContext ec) { _executionContext = ec; } static internal ContextCallback _ccb = new ContextCallback(ThreadStart_Context); static internal void ThreadStart_Context(Object state) { ThreadHelper t = (ThreadHelper)state; if (t._start is ThreadStart) { ((ThreadStart)t._start)(); } else { ((ParameterizedThreadStart)t._start)(t._startArg); } } // call back helper internal void ThreadStart(object obj) { _startArg = obj; if (_executionContext != null) { ExecutionContext.Run(_executionContext, _ccb, (Object)this); } else { ((ParameterizedThreadStart)_start)(obj); } } // call back helper internal void ThreadStart() { if (_executionContext != null) { ExecutionContext.Run(_executionContext, _ccb, (Object)this); } else { ((ThreadStart)_start)(); } } }; // deliberately not [serializable] [ClassInterface(ClassInterfaceType.None)] [ComDefaultInterface(typeof(_Thread))] [System.Runtime.InteropServices.ComVisible(true)] public sealed class Thread : CriticalFinalizerObject, _Thread { /*========================================================================= ** Data accessed from managed code that needs to be defined in ** ThreadBaseObject to maintain alignment between the two classes. ** DON'T CHANGE THESE UNLESS YOU MODIFY ThreadBaseObject in vm\object.h =========================================================================*/ private Context m_Context; private ExecutionContext m_ExecutionContext; // this call context follows the logical thread private String m_Name; private Delegate m_Delegate; // Delegate private Object[][] m_ThreadStaticsBuckets; // Holder for thread statics private int[] m_ThreadStaticsBits; // Bit-markers for slot availability private CultureInfo m_CurrentCulture; private CultureInfo m_CurrentUICulture; #if IO_CANCELLATION_ENABLED internal Listm_CancellationSignals; // IO Cancellation stack #endif private Object m_ThreadStartArg; /*========================================================================= ** The base implementation of Thread is all native. The following fields ** should never be used in the C# code. They are here to define the proper ** space so the thread object may be allocated. DON'T CHANGE THESE UNLESS ** YOU MODIFY ThreadBaseObject in vm\object.h =========================================================================*/ #pragma warning disable 169 #pragma warning disable 414 // These fields are not used from managed. // IntPtrs need to be together, and before ints, because IntPtrs are 64-bit // fields on 64-bit platforms, where they will be sorted together. private IntPtr DONT_USE_InternalThread; // Pointer private int m_Priority; // INT32 private int m_ManagedThreadId; // INT32 #pragma warning restore 414 #pragma warning restore 169 /*========================================================================= ** This manager is responsible for storing the global data that is ** shared amongst all the thread local stores. =========================================================================*/ static private LocalDataStoreMgr s_LocalDataStoreMgr = null; static private Object s_SyncObject = new Object(); // Has to be in [....] with THREAD_STATICS_BUCKET_SIZE in vm/threads.cpp private const int STATICS_BUCKET_SIZE = 32; /*========================================================================== ** Creates a new Thread object which will begin execution at ** start.ThreadStart on a new thread when the Start method is called. ** ** Exceptions: ArgumentNullException if start == null. =========================================================================*/ public Thread(ThreadStart start) { if (start == null) { throw new ArgumentNullException("start"); } SetStartHelper((Delegate)start,0); //0 will setup Thread with default stackSize } public Thread(ThreadStart start, int maxStackSize) { if (start == null) { throw new ArgumentNullException("start"); } if (0 > maxStackSize) throw new ArgumentOutOfRangeException("maxStackSize",Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); SetStartHelper((Delegate)start, maxStackSize); } public Thread(ParameterizedThreadStart start) { if (start == null) { throw new ArgumentNullException("start"); } SetStartHelper((Delegate)start, 0); } public Thread(ParameterizedThreadStart start, int maxStackSize) { if (start == null) { throw new ArgumentNullException("start"); } if (0 > maxStackSize) throw new ArgumentOutOfRangeException("maxStackSize",Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); SetStartHelper((Delegate)start, maxStackSize); } [ComVisible(false), MethodImplAttribute(MethodImplOptions.InternalCall)] public extern override int GetHashCode(); public int ManagedThreadId { [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] get { return m_ManagedThreadId; } } /*========================================================================= ** Spawns off a new thread which will begin executing at the ThreadStart ** method on the IThreadable interface passed in the constructor. Once the ** thread is dead, it cannot be restarted with another call to Start. ** ** Exceptions: ThreadStateException if the thread has already been started. =========================================================================*/ [HostProtection(Synchronization=true,ExternalThreading=true)] [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable public void Start() { #if FEATURE_COMINTEROP // Eagerly initialize the COM Apartment state of the thread if we're allowed to. StartupSetApartmentStateInternal(); #endif // FEATURE_COMINTEROP // Attach current thread's security principal object to the new // thread. Be careful not to bind the current thread to a principal // if it's not already bound. if (m_Delegate != null) { // If we reach here with a null delegate, something is broken. But we'll let the StartInternal method take care of // reporting an error. Just make sure we dont try to dereference a null delegate. ThreadHelper t = (ThreadHelper)(m_Delegate.Target); ExecutionContext ec = ExecutionContext.Capture(); ExecutionContext.ClearSyncContext(ec); t.SetExecutionContextHelper(ec); } IPrincipal principal = (IPrincipal) CallContext.Principal; StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; StartInternal(principal, ref stackMark); } [HostProtection(Synchronization=true,ExternalThreading=true)] public void Start(object parameter) { //In the case of a null delegate (second call to start on same thread) // StartInternal method will take care of the error reporting if(m_Delegate is ThreadStart) { //We expect the thread to be setup with a ParameterizedThreadStart // if this constructor is called. //If we got here then that wasn't the case throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ThreadWrongThreadStart")); } m_ThreadStartArg = parameter; Start(); } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] internal ExecutionContext GetExecutionContextNoCreate() { return m_ExecutionContext; } public ExecutionContext ExecutionContext { [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] get { if (m_ExecutionContext == null && this == Thread.CurrentThread) { m_ExecutionContext = new ExecutionContext(); m_ExecutionContext.Thread = this; } return m_ExecutionContext; } } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] internal void SetExecutionContext(ExecutionContext value) { m_ExecutionContext = value; if (value != null) m_ExecutionContext.Thread = this; } [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern void StartInternal(IPrincipal principal, ref StackCrawlMark stackMark); /// [StrongNameIdentityPermissionAttribute(SecurityAction.LinkDemand, PublicKey = "0x00000000000000000400000000000000"), SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode), DynamicSecurityMethodAttribute()] [Obsolete("Thread.SetCompressedStack is no longer supported. Please use the System.Threading.CompressedStack class")] public void SetCompressedStack( CompressedStack stack ) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ThreadAPIsNotSupported")); } [MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] internal extern IntPtr SetAppDomainStack( SafeCompressedStackHandle csHandle); [MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] internal extern void RestoreAppDomainStack( IntPtr appDomainStack); /// [StrongNameIdentityPermissionAttribute(SecurityAction.LinkDemand, PublicKey = "0x00000000000000000400000000000000"), SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] [Obsolete("Thread.GetCompressedStack is no longer supported. Please use the System.Threading.CompressedStack class")] public CompressedStack GetCompressedStack() { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ThreadAPIsNotSupported")); } // Helper method to get a logical thread ID for StringBuilder (for // correctness) and for FileStream's async code path (for perf, to // avoid creating a Thread instance). [MethodImplAttribute(MethodImplOptions.InternalCall)] internal extern static IntPtr InternalGetCurrentThread(); #if IO_CANCELLATION_ENABLED // Internal method to get the OS thread handle for this thread. internal extern IntPtr Handle { [MethodImpl(MethodImplOptions.InternalCall)] get; } #endif /*========================================================================== ** Raises a ThreadAbortException in the thread, which usually ** results in the thread's death. The ThreadAbortException is a special ** exception that is not catchable. The finally clauses of all try ** statements will be executed before the thread dies. This includes the ** finally that a thread might be executing at the moment the Abort is raised. ** The thread is not stopped immediately--you must Join on the ** thread to guarantee it has stopped. ** It is possible for a thread to do an unbounded amount of computation in ** the finally's and thus indefinitely delay the threads death. ** If Abort() is called on a thread that has not been started, the thread ** will abort when Start() is called. ** If Abort is called twice on the same thread, a DuplicateThreadAbort ** exception is thrown. =========================================================================*/ [SecurityPermissionAttribute(SecurityAction.Demand, ControlThread=true)] public void Abort(Object stateInfo) { // If two aborts come at the same time, it is possible that the state info // gets set by one, and the actual abort gets delivered by another. But this // is not distinguishable by an application. // The accessor helper will only set the value if it isn't already set, // and that particular bit of native code can test much faster than this // code could, because testing might cause a cross-appdomain marshalling. AbortReason = stateInfo; // Note: we demand ControlThread permission, then call AbortInternal directly // rather than delegating to the Abort() function below. We do this to ensure // that only callers with ControlThread are allowed to change the AbortReason // of the thread. We call AbortInternal directly to avoid demanding the same // permission twice. AbortInternal(); } [SecurityPermissionAttribute(SecurityAction.Demand, ControlThread=true)] public void Abort() { AbortInternal(); } // Internal helper (since we can't place security demands on // ecalls/fcalls). [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern void AbortInternal(); /*========================================================================== ** Resets a thread abort. ** Should be called by trusted code only =========================================================================*/ [SecurityPermissionAttribute(SecurityAction.Demand, ControlThread=true)] public static void ResetAbort() { Thread thread = Thread.CurrentThread; if ((thread.ThreadState & ThreadState.AbortRequested) == 0) throw new ThreadStateException(Environment.GetResourceString("ThreadState_NoAbortRequested")); thread.ResetAbortNative(); thread.ClearAbortReason(); } [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern void ResetAbortNative(); /*========================================================================= ** Suspends the thread. If the thread is already suspended, this call has ** no effect. ** ** Exceptions: ThreadStateException if the thread has not been started or ** it is dead. =========================================================================*/ [Obsolete("Thread.Suspend has been deprecated. Please use other classes in System.Threading, such as Monitor, Mutex, Event, and Semaphore, to synchronize Threads or protect resources. http://go.microsoft.com/fwlink/?linkid=14202", false)][SecurityPermission(SecurityAction.Demand, ControlThread=true)] [SecurityPermission(SecurityAction.Demand, ControlThread=true)] public void Suspend() { SuspendInternal(); } // Internal helper (since we can't place security demands on // ecalls/fcalls). [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern void SuspendInternal(); /*========================================================================== ** Resumes a thread that has been suspended. ** ** Exceptions: ThreadStateException if the thread has not been started or ** it is dead or it isn't in the suspended state. =========================================================================*/ [Obsolete("Thread.Resume has been deprecated. Please use other classes in System.Threading, such as Monitor, Mutex, Event, and Semaphore, to synchronize Threads or protect resources. http://go.microsoft.com/fwlink/?linkid=14202", false)] [SecurityPermission(SecurityAction.Demand, ControlThread=true)] public void Resume() { ResumeInternal(); } // Internal helper (since we can't place security demands on // ecalls/fcalls). [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern void ResumeInternal(); /*========================================================================= ** Interrupts a thread that is inside a Wait(), Sleep() or Join(). If that ** thread is not currently blocked in that manner, it will be interrupted ** when it next begins to block. =========================================================================*/ [SecurityPermission(SecurityAction.Demand, ControlThread=true)] public void Interrupt() { InterruptInternal(); } // Internal helper (since we can't place security demands on // ecalls/fcalls). [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern void InterruptInternal(); /*========================================================================= ** Returns the priority of the thread. ** ** Exceptions: ThreadStateException if the thread is dead. =========================================================================*/ public ThreadPriority Priority { get { return (ThreadPriority)GetPriorityNative(); } [HostProtection(SelfAffectingThreading=true)] set { SetPriorityNative((int)value); } } [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern int GetPriorityNative(); [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern void SetPriorityNative(int priority); /*========================================================================= ** Returns true if the thread has been started and is not dead. =========================================================================*/ public bool IsAlive { get { return IsAliveNative(); } } [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern bool IsAliveNative(); /*========================================================================== ** Returns true if the thread is a threadpool thread. =========================================================================*/ public bool IsThreadPoolThread { get { return IsThreadpoolThreadNative(); } } [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern bool IsThreadpoolThreadNative(); /*========================================================================= ** Waits for the thread to die. ** ** Exceptions: ThreadInterruptedException if the thread is interrupted while waiting. ** ThreadStateException if the thread has not been started yet. =========================================================================*/ [MethodImplAttribute(MethodImplOptions.InternalCall)] [HostProtection(Synchronization=true, ExternalThreading=true)] private extern void JoinInternal(); [HostProtection(Synchronization=true, ExternalThreading=true)] public void Join() { JoinInternal(); } /*========================================================================== ** Waits for the thread to die or for timeout milliseconds to elapse. ** Returns true if the thread died, or false if the wait timed out. If ** Timeout.Infinite is given as the parameter, no timeout will occur. ** ** Exceptions: ArgumentException if timeout < 0. ** ThreadInterruptedException if the thread is interrupted while waiting. ** ThreadStateException if the thread has not been started yet. =========================================================================*/ [MethodImplAttribute(MethodImplOptions.InternalCall)] [HostProtection(Synchronization=true, ExternalThreading=true)] private extern bool JoinInternal(int millisecondsTimeout); [HostProtection(Synchronization=true, ExternalThreading=true)] public bool Join(int millisecondsTimeout) { return JoinInternal(millisecondsTimeout); } [HostProtection(Synchronization=true, ExternalThreading=true)] public bool Join(TimeSpan timeout) { long tm = (long)timeout.TotalMilliseconds; if (tm < -1 || tm > (long) Int32.MaxValue) throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); return Join((int)tm); } /*========================================================================== ** Suspends the current thread for timeout milliseconds. If timeout == 0, ** forces the thread to give up the remainer of its timeslice. If timeout ** == Timeout.Infinite, no timeout will occur. ** ** Exceptions: ArgumentException if timeout < 0. ** ThreadInterruptedException if the thread is interrupted while sleeping. =========================================================================*/ [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern void SleepInternal(int millisecondsTimeout); public static void Sleep(int millisecondsTimeout) { SleepInternal(millisecondsTimeout); } public static void Sleep(TimeSpan timeout) { long tm = (long)timeout.TotalMilliseconds; if (tm < -1 || tm > (long) Int32.MaxValue) throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); Sleep((int)tm); } /* wait for a length of time proportial to 'iterations'. Each iteration is should only take a few machine instructions. Calling this API is preferable to coding a explict busy loop because the hardware can be informed that it is busy waiting. */ [MethodImplAttribute(MethodImplOptions.InternalCall), HostProtection(Synchronization=true,ExternalThreading=true), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] private static extern void SpinWaitInternal(int iterations); [HostProtection(Synchronization=true,ExternalThreading=true), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] public static void SpinWait(int iterations) { SpinWaitInternal(iterations); } public static Thread CurrentThread { [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] get { Thread th; th = GetFastCurrentThreadNative(); if (th == null) th = GetCurrentThreadNative(); return th; } } [MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] private static extern Thread GetCurrentThreadNative(); [MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] private static extern Thread GetFastCurrentThreadNative(); private void SetStartHelper(Delegate start, int maxStackSize) { ThreadHelper threadStartCallBack = new ThreadHelper(start); if(start is ThreadStart) { SetStart(new ThreadStart(threadStartCallBack.ThreadStart), maxStackSize); } else { SetStart(new ParameterizedThreadStart(threadStartCallBack.ThreadStart), maxStackSize); } } /*========================================================================= ** PRIVATE Sets the IThreadable interface for the thread. Assumes that ** start != null. =========================================================================*/ [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern void SetStart(Delegate start, int maxStackSize); /*========================================================================== ** Clean up the thread when it goes away. =========================================================================*/ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] ~Thread() { // Delegate to the unmanaged portion. InternalFinalize(); } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern void InternalFinalize(); /*========================================================================= ** Return whether or not this thread is a background thread. Background ** threads do not affect when the Execution Engine shuts down. ** ** Exceptions: ThreadStateException if the thread is dead. =========================================================================*/ public bool IsBackground { get { return IsBackgroundNative(); } [HostProtection(SelfAffectingThreading=true)] set { SetBackgroundNative(value); } } [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern bool IsBackgroundNative(); [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern void SetBackgroundNative(bool isBackground); /*========================================================================= ** Return the thread state as a consistent set of bits. This is more ** general then IsAlive or IsBackground. =========================================================================*/ public ThreadState ThreadState { get { return (ThreadState)GetThreadStateNative(); } } [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern int GetThreadStateNative(); #if FEATURE_COMINTEROP /*========================================================================= ** An unstarted thread can be marked to indicate that it will host a ** single-threaded or multi-threaded apartment. ** ** Exceptions: ArgumentException if state is not a valid apartment state ** (ApartmentSTA or ApartmentMTA). =========================================================================*/ [Obsolete("The ApartmentState property has been deprecated. Use GetApartmentState, SetApartmentState or TrySetApartmentState instead.", false)] public ApartmentState ApartmentState { get { return (ApartmentState)GetApartmentStateNative(); } [HostProtection(Synchronization=true, SelfAffectingThreading=true)] set { SetApartmentStateNative((int)value, true); } } public ApartmentState GetApartmentState() { return (ApartmentState)GetApartmentStateNative(); } [HostProtection(Synchronization=true, SelfAffectingThreading=true)] public bool TrySetApartmentState(ApartmentState state) { return SetApartmentStateHelper(state, false); } [HostProtection(Synchronization=true, SelfAffectingThreading=true)] public void SetApartmentState(ApartmentState state) { bool result = SetApartmentStateHelper(state, true); if (!result) throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ApartmentStateSwitchFailed")); } private bool SetApartmentStateHelper(ApartmentState state, bool fireMDAOnMismatch) { ApartmentState retState = (ApartmentState)SetApartmentStateNative((int)state, fireMDAOnMismatch); // Special case where we pass in Unknown and get back MTA. // Once we CoUninitialize the thread, the OS will still // report the thread as implicitly in the MTA if any // other thread in the process is CoInitialized. if ((state == System.Threading.ApartmentState.Unknown) && (retState == System.Threading.ApartmentState.MTA)) return true; if (retState != state) return false; return true; } [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern int GetApartmentStateNative(); [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern int SetApartmentStateNative(int state, bool fireMDAOnMismatch); [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern int StartupSetApartmentStateInternal(); #endif // FEATURE_COMINTEROP /*========================================================================== ** Allocates an un-named data slot. The slot is allocated on ALL the ** threads. =========================================================================*/ [HostProtection(SharedState=true, ExternalThreading=true)] public static LocalDataStoreSlot AllocateDataSlot() { return LocalDataStoreManager.AllocateDataSlot(); } /*========================================================================= ** Allocates a named data slot. The slot is allocated on ALL the ** threads. Named data slots are "public" and can be manipulated by ** anyone. =========================================================================*/ [HostProtection(SharedState=true, ExternalThreading=true)] public static LocalDataStoreSlot AllocateNamedDataSlot(String name) { return LocalDataStoreManager.AllocateNamedDataSlot(name); } /*========================================================================== ** Looks up a named data slot. If the name has not been used, a new slot is ** allocated. Named data slots are "public" and can be manipulated by ** anyone. =========================================================================*/ [HostProtection(SharedState=true, ExternalThreading=true)] public static LocalDataStoreSlot GetNamedDataSlot(String name) { return LocalDataStoreManager.GetNamedDataSlot(name); } /*========================================================================== ** Frees a named data slot. The slot is allocated on ALL the ** threads. Named data slots are "public" and can be manipulated by ** anyone. =========================================================================*/ [HostProtection(SharedState=true, ExternalThreading=true)] public static void FreeNamedDataSlot(String name) { LocalDataStoreManager.FreeNamedDataSlot(name); } /*========================================================================= ** Retrieves the value from the specified slot on the current thread, for that thread's current domain. =========================================================================*/ [HostProtection(SharedState=true, ExternalThreading=true)] [ResourceExposure(ResourceScope.AppDomain)] public static Object GetData(LocalDataStoreSlot slot) { LocalDataStoreManager.ValidateSlot(slot); LocalDataStore dls = GetDomainLocalStore(); if (dls == null) return null; return dls.GetData(slot); } /*========================================================================== ** Sets the data in the specified slot on the currently running thread, for that thread's current domain. =========================================================================*/ [HostProtection(SharedState=true, ExternalThreading=true)] [ResourceExposure(ResourceScope.AppDomain)] public static void SetData(LocalDataStoreSlot slot, Object data) { LocalDataStore dls = GetDomainLocalStore(); // Create new DLS if one hasn't been created for this domain for this thread if (dls == null) { dls = LocalDataStoreManager.CreateLocalDataStore(); SetDomainLocalStore(dls); } dls.SetData(slot, data); } [MethodImplAttribute(MethodImplOptions.InternalCall)] [ResourceExposure(ResourceScope.AppDomain)] static extern private LocalDataStore GetDomainLocalStore(); [MethodImplAttribute(MethodImplOptions.InternalCall)] [ResourceExposure(ResourceScope.AppDomain)] static extern private void SetDomainLocalStore(LocalDataStore dls); /*** * An appdomain has been unloaded - remove its DLS from the manager */ static private void RemoveDomainLocalStore(LocalDataStore dls) { if (dls != null) LocalDataStoreManager.DeleteLocalDataStore(dls); } [MethodImplAttribute(MethodImplOptions.InternalCall)] static extern private bool nativeGetSafeCulture(Thread t, int appDomainId, bool isUI, ref CultureInfo safeCulture); // As the culture can be customized object then we cannot hold any // reference to it before we check if it is safe because the app domain // owning this customized culture may get unloaded while executing this // code. To achieve that we have to do the check using nativeGetSafeCulture // as the thread cannot get interrupted during the FCALL. // If the culture is safe (not customized or created in current app domain) // then the FCALL will return a reference to that culture otherwise the // FCALL will return failure. In case of failure we'll return the default culture. // If the app domain owning a customized culture that is set to teh thread and this // app domain get unloaded there is a code to clean up the culture from the thread // using the code in AppDomain::ReleaseDomainStores. public CultureInfo CurrentUICulture { get { // Fetch a local copy of m_CurrentUICulture to // avoid ----s that malicious user can introduce if (m_CurrentUICulture == null) { return CultureInfo.UserDefaultUICulture; } CultureInfo culture = null; if (!nativeGetSafeCulture(this, GetDomainID(), true, ref culture) || culture == null) { return CultureInfo.UserDefaultUICulture; } return culture; } [HostProtection(ExternalThreading=true)] set { if (value == null) { throw new ArgumentNullException("value"); } //If they're trying to use a Culture with a name that we can't use in resource lookup, //don't even let them set it on the thread. CultureInfo.VerifyCultureName(value, true); if (nativeSetThreadUILocale(value.LCID) == false) { throw new ArgumentException(Environment.GetResourceString("Argument_InvalidResourceCultureName", value.Name)); } value.StartCrossDomainTracking(); m_CurrentUICulture = value; } } // This returns the exposed context for a given context ID. [MethodImplAttribute(MethodImplOptions.InternalCall)] static extern private bool nativeSetThreadUILocale(int LCID); // As the culture can be customized object then we cannot hold any // reference to it before we check if it is safe because the app domain // owning this customized culture may get unloaded while executing this // code. To achieve that we have to do the check using nativeGetSafeCulture // as the thread cannot get interrupted during the FCALL. // If the culture is safe (not customized or created in current app domain) // then the FCALL will return a reference to that culture otherwise the // FCALL will return failure. In case of failure we'll return the default culture. // If the app domain owning a customized culture that is set to teh thread and this // app domain get unloaded there is a code to clean up the culture from the thread // using the code in AppDomain::ReleaseDomainStores. public CultureInfo CurrentCulture { get { // Fetch a local copy of m_CurrentCulture to // avoid ----s that malicious user can introduce if (m_CurrentCulture == null) { return CultureInfo.UserDefaultCulture; } CultureInfo culture = null; if (!nativeGetSafeCulture(this, GetDomainID(), false, ref culture) || culture == null) { return CultureInfo.UserDefaultCulture; } return culture; } [SecurityPermission(SecurityAction.Demand, ControlThread=true)] set { if (null==value) { throw new ArgumentNullException("value"); } CultureInfo.CheckNeutral(value); //If we can't set the nativeThreadLocale, we'll just let it stay //at whatever value it had before. This allows people who use //just managed code not to be limited by the underlying OS. CultureInfo.nativeSetThreadLocale(value.LCID); value.StartCrossDomainTracking(); m_CurrentCulture = value; } } /*=============================================================== ====================== Thread Statics =========================== ===============================================================*/ private int ReserveSlot() { // This is called by the thread on itself so no need for locks if (m_ThreadStaticsBuckets == null) { BCLDebug.Assert(STATICS_BUCKET_SIZE % 32 == 0,"STATICS_BUCKET_SIZE should be a multiple of 32"); // allocate bucket holder // do not publish the data until all the intialization is done, in case of asynchronized exceptions Object[][] newBuckets = new Object[1][]; SetIsThreadStaticsArray(newBuckets); // allocate the first bucket newBuckets[0] = new Object[STATICS_BUCKET_SIZE]; SetIsThreadStaticsArray(newBuckets[0]); int[] newBits = new int[newBuckets.Length*STATICS_BUCKET_SIZE/32]; // use memset! for (int i=0; i all slots occupied if (slot == 0) { // We need to expand. Allocate a new bucket int oldLength = m_ThreadStaticsBuckets.Length; int oldLengthBits = m_ThreadStaticsBits.Length; int newLength = m_ThreadStaticsBuckets.Length + 1; Object[][] newBuckets = new Object[newLength][]; SetIsThreadStaticsArray(newBuckets); int newLengthBits = newLength*STATICS_BUCKET_SIZE/32; int[] newBits = new int[newLengthBits]; // Copy old buckets into new holder Array.Copy(m_ThreadStaticsBuckets, newBuckets, m_ThreadStaticsBuckets.Length); // Allocate new buckets for (int i = oldLength ; i < newLength ; i++) { newBuckets[i] = new Object[STATICS_BUCKET_SIZE]; SetIsThreadStaticsArray(newBuckets[i]); } // Copy old bits into new bit array Array.Copy(m_ThreadStaticsBits, newBits, m_ThreadStaticsBits.Length); // Initalize new bits for(int i= oldLengthBits ; i >16)&0xffff; slot+=16; } if ((bits & 0xff) != 0) { bits = bits & 0xff; } else { slot+=8; bits = (bits>>8)&0xff; } int j; for (j=0; j<8; j++) { if ( (bits & (1< CancellationSignals { [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] get { if (m_CancellationSignals == null) { List signals = new List (); Interlocked.CompareExchange(ref m_CancellationSignals, signals, null); } return m_CancellationSignals; } } #endif /*========================================================================== ** Volatile Read & Write and MemoryBarrier methods. ** Provides the ability to read and write values ensuring that the values ** are read/written each time they are accessed. =========================================================================*/ [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static byte VolatileRead(ref byte address) { byte ret = address; MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. return ret; } [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static short VolatileRead(ref short address) { short ret = address; MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. return ret; } [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static int VolatileRead(ref int address) { int ret = address; MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. return ret; } [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static long VolatileRead(ref long address) { long ret = address; MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. return ret; } [CLSCompliant(false)] [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static sbyte VolatileRead(ref sbyte address) { sbyte ret = address; MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. return ret; } [CLSCompliant(false)] [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static ushort VolatileRead(ref ushort address) { ushort ret = address; MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. return ret; } [CLSCompliant(false)] [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static uint VolatileRead(ref uint address) { uint ret = address; MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. return ret; } [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static IntPtr VolatileRead(ref IntPtr address) { IntPtr ret = address; MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. return ret; } [CLSCompliant(false)] [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static UIntPtr VolatileRead(ref UIntPtr address) { UIntPtr ret = address; MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. return ret; } [CLSCompliant(false)] [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static ulong VolatileRead(ref ulong address) { ulong ret = address; MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. return ret; } [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static float VolatileRead(ref float address) { float ret = address; MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. return ret; } [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static double VolatileRead(ref double address) { double ret = address; MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. return ret; } [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static Object VolatileRead(ref Object address) { Object ret = address; MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. return ret; } [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static void VolatileWrite(ref byte address, byte value) { MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. address = value; } [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static void VolatileWrite(ref short address, short value) { MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. address = value; } [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static void VolatileWrite(ref int address, int value) { MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. address = value; } [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static void VolatileWrite(ref long address, long value) { MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. address = value; } [CLSCompliant(false)] [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static void VolatileWrite(ref sbyte address, sbyte value) { MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. address = value; } [CLSCompliant(false)] [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static void VolatileWrite(ref ushort address, ushort value) { MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. address = value; } [CLSCompliant(false)] [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static void VolatileWrite(ref uint address, uint value) { MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. address = value; } [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static void VolatileWrite(ref IntPtr address, IntPtr value) { MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. address = value; } [CLSCompliant(false)] [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static void VolatileWrite(ref UIntPtr address, UIntPtr value) { MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. address = value; } [CLSCompliant(false)] [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static void VolatileWrite(ref ulong address, ulong value) { MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. address = value; } [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static void VolatileWrite(ref float address, float value) { MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. address = value; } [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static void VolatileWrite(ref double address, double value) { MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. address = value; } [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static void VolatileWrite(ref Object address, Object value) { MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. address = value; } [MethodImplAttribute(MethodImplOptions.InternalCall)] public static extern void MemoryBarrier(); //We need to mark thread statics array for AppDomain leak checking purpose [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern void SetIsThreadStaticsArray(Object o); private static LocalDataStoreMgr LocalDataStoreManager { get { if (s_LocalDataStoreMgr == null) { lock(s_SyncObject) { if (s_LocalDataStoreMgr == null) s_LocalDataStoreMgr = new LocalDataStoreMgr(); } } return s_LocalDataStoreMgr; } } void _Thread.GetTypeInfoCount(out uint pcTInfo) { throw new NotImplementedException(); } void _Thread.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo) { throw new NotImplementedException(); } void _Thread.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId) { throw new NotImplementedException(); } void _Thread.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr) { throw new NotImplementedException(); } // Helper function to set the AbortReason for a thread abort. // Checks that they're not alredy set, and then atomically updates // the reason info (object + ADID). [MethodImplAttribute(MethodImplOptions.InternalCall)] internal extern void SetAbortReason(Object o); // Helper function to retrieve the AbortReason from a thread // abort. Will perform cross-AppDomain marshalling if the object // lives in a different AppDomain from the requester. [MethodImplAttribute(MethodImplOptions.InternalCall)] internal extern Object GetAbortReason(); // Helper function to clear the AbortReason. Takes care of // AppDomain related cleanup if required. [MethodImplAttribute(MethodImplOptions.InternalCall)] internal extern void ClearAbortReason(); } // End of class Thread // declaring a local var of this enum type and passing it by ref into a function that needs to do a // stack crawl will both prevent inlining of the calle and pass an ESP point to stack crawl to // Declaring these in EH clauses is illegal; they must declared in the main method body [Serializable] internal enum StackCrawlMark { LookForMe = 0, LookForMyCaller = 1, LookForMyCallersCaller = 2, LookForThread = 3 } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== /*============================================================================== ** ** Class: Thread ** ** ** Purpose: Class for creating and managing a thread. ** ** =============================================================================*/ namespace System.Threading { using System.Threading; using System.Runtime.InteropServices; using System.Runtime.Remoting.Contexts; using System.Runtime.Remoting.Messaging; using System; using System.Diagnostics; using System.Security.Permissions; using System.Security.Principal; using System.Globalization; using System.Collections.Generic; using System.Runtime.Serialization; using System.Runtime.CompilerServices; using System.Runtime.ConstrainedExecution; using System.Security; using System.Runtime.Versioning; internal delegate Object InternalCrossContextDelegate(Object[] args); internal class ThreadHelper { Delegate _start; Object _startArg = null; ExecutionContext _executionContext = null; internal ThreadHelper(Delegate start) { _start = start; } internal void SetExecutionContextHelper(ExecutionContext ec) { _executionContext = ec; } static internal ContextCallback _ccb = new ContextCallback(ThreadStart_Context); static internal void ThreadStart_Context(Object state) { ThreadHelper t = (ThreadHelper)state; if (t._start is ThreadStart) { ((ThreadStart)t._start)(); } else { ((ParameterizedThreadStart)t._start)(t._startArg); } } // call back helper internal void ThreadStart(object obj) { _startArg = obj; if (_executionContext != null) { ExecutionContext.Run(_executionContext, _ccb, (Object)this); } else { ((ParameterizedThreadStart)_start)(obj); } } // call back helper internal void ThreadStart() { if (_executionContext != null) { ExecutionContext.Run(_executionContext, _ccb, (Object)this); } else { ((ThreadStart)_start)(); } } }; // deliberately not [serializable] [ClassInterface(ClassInterfaceType.None)] [ComDefaultInterface(typeof(_Thread))] [System.Runtime.InteropServices.ComVisible(true)] public sealed class Thread : CriticalFinalizerObject, _Thread { /*========================================================================= ** Data accessed from managed code that needs to be defined in ** ThreadBaseObject to maintain alignment between the two classes. ** DON'T CHANGE THESE UNLESS YOU MODIFY ThreadBaseObject in vm\object.h =========================================================================*/ private Context m_Context; private ExecutionContext m_ExecutionContext; // this call context follows the logical thread private String m_Name; private Delegate m_Delegate; // Delegate private Object[][] m_ThreadStaticsBuckets; // Holder for thread statics private int[] m_ThreadStaticsBits; // Bit-markers for slot availability private CultureInfo m_CurrentCulture; private CultureInfo m_CurrentUICulture; #if IO_CANCELLATION_ENABLED internal List m_CancellationSignals; // IO Cancellation stack #endif private Object m_ThreadStartArg; /*========================================================================= ** The base implementation of Thread is all native. The following fields ** should never be used in the C# code. They are here to define the proper ** space so the thread object may be allocated. DON'T CHANGE THESE UNLESS ** YOU MODIFY ThreadBaseObject in vm\object.h =========================================================================*/ #pragma warning disable 169 #pragma warning disable 414 // These fields are not used from managed. // IntPtrs need to be together, and before ints, because IntPtrs are 64-bit // fields on 64-bit platforms, where they will be sorted together. private IntPtr DONT_USE_InternalThread; // Pointer private int m_Priority; // INT32 private int m_ManagedThreadId; // INT32 #pragma warning restore 414 #pragma warning restore 169 /*========================================================================= ** This manager is responsible for storing the global data that is ** shared amongst all the thread local stores. =========================================================================*/ static private LocalDataStoreMgr s_LocalDataStoreMgr = null; static private Object s_SyncObject = new Object(); // Has to be in [....] with THREAD_STATICS_BUCKET_SIZE in vm/threads.cpp private const int STATICS_BUCKET_SIZE = 32; /*========================================================================== ** Creates a new Thread object which will begin execution at ** start.ThreadStart on a new thread when the Start method is called. ** ** Exceptions: ArgumentNullException if start == null. =========================================================================*/ public Thread(ThreadStart start) { if (start == null) { throw new ArgumentNullException("start"); } SetStartHelper((Delegate)start,0); //0 will setup Thread with default stackSize } public Thread(ThreadStart start, int maxStackSize) { if (start == null) { throw new ArgumentNullException("start"); } if (0 > maxStackSize) throw new ArgumentOutOfRangeException("maxStackSize",Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); SetStartHelper((Delegate)start, maxStackSize); } public Thread(ParameterizedThreadStart start) { if (start == null) { throw new ArgumentNullException("start"); } SetStartHelper((Delegate)start, 0); } public Thread(ParameterizedThreadStart start, int maxStackSize) { if (start == null) { throw new ArgumentNullException("start"); } if (0 > maxStackSize) throw new ArgumentOutOfRangeException("maxStackSize",Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); SetStartHelper((Delegate)start, maxStackSize); } [ComVisible(false), MethodImplAttribute(MethodImplOptions.InternalCall)] public extern override int GetHashCode(); public int ManagedThreadId { [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] get { return m_ManagedThreadId; } } /*========================================================================= ** Spawns off a new thread which will begin executing at the ThreadStart ** method on the IThreadable interface passed in the constructor. Once the ** thread is dead, it cannot be restarted with another call to Start. ** ** Exceptions: ThreadStateException if the thread has already been started. =========================================================================*/ [HostProtection(Synchronization=true,ExternalThreading=true)] [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable public void Start() { #if FEATURE_COMINTEROP // Eagerly initialize the COM Apartment state of the thread if we're allowed to. StartupSetApartmentStateInternal(); #endif // FEATURE_COMINTEROP // Attach current thread's security principal object to the new // thread. Be careful not to bind the current thread to a principal // if it's not already bound. if (m_Delegate != null) { // If we reach here with a null delegate, something is broken. But we'll let the StartInternal method take care of // reporting an error. Just make sure we dont try to dereference a null delegate. ThreadHelper t = (ThreadHelper)(m_Delegate.Target); ExecutionContext ec = ExecutionContext.Capture(); ExecutionContext.ClearSyncContext(ec); t.SetExecutionContextHelper(ec); } IPrincipal principal = (IPrincipal) CallContext.Principal; StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; StartInternal(principal, ref stackMark); } [HostProtection(Synchronization=true,ExternalThreading=true)] public void Start(object parameter) { //In the case of a null delegate (second call to start on same thread) // StartInternal method will take care of the error reporting if(m_Delegate is ThreadStart) { //We expect the thread to be setup with a ParameterizedThreadStart // if this constructor is called. //If we got here then that wasn't the case throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ThreadWrongThreadStart")); } m_ThreadStartArg = parameter; Start(); } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] internal ExecutionContext GetExecutionContextNoCreate() { return m_ExecutionContext; } public ExecutionContext ExecutionContext { [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] get { if (m_ExecutionContext == null && this == Thread.CurrentThread) { m_ExecutionContext = new ExecutionContext(); m_ExecutionContext.Thread = this; } return m_ExecutionContext; } } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] internal void SetExecutionContext(ExecutionContext value) { m_ExecutionContext = value; if (value != null) m_ExecutionContext.Thread = this; } [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern void StartInternal(IPrincipal principal, ref StackCrawlMark stackMark); /// [StrongNameIdentityPermissionAttribute(SecurityAction.LinkDemand, PublicKey = "0x00000000000000000400000000000000"), SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode), DynamicSecurityMethodAttribute()] [Obsolete("Thread.SetCompressedStack is no longer supported. Please use the System.Threading.CompressedStack class")] public void SetCompressedStack( CompressedStack stack ) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ThreadAPIsNotSupported")); } [MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] internal extern IntPtr SetAppDomainStack( SafeCompressedStackHandle csHandle); [MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] internal extern void RestoreAppDomainStack( IntPtr appDomainStack); /// [StrongNameIdentityPermissionAttribute(SecurityAction.LinkDemand, PublicKey = "0x00000000000000000400000000000000"), SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] [Obsolete("Thread.GetCompressedStack is no longer supported. Please use the System.Threading.CompressedStack class")] public CompressedStack GetCompressedStack() { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ThreadAPIsNotSupported")); } // Helper method to get a logical thread ID for StringBuilder (for // correctness) and for FileStream's async code path (for perf, to // avoid creating a Thread instance). [MethodImplAttribute(MethodImplOptions.InternalCall)] internal extern static IntPtr InternalGetCurrentThread(); #if IO_CANCELLATION_ENABLED // Internal method to get the OS thread handle for this thread. internal extern IntPtr Handle { [MethodImpl(MethodImplOptions.InternalCall)] get; } #endif /*========================================================================== ** Raises a ThreadAbortException in the thread, which usually ** results in the thread's death. The ThreadAbortException is a special ** exception that is not catchable. The finally clauses of all try ** statements will be executed before the thread dies. This includes the ** finally that a thread might be executing at the moment the Abort is raised. ** The thread is not stopped immediately--you must Join on the ** thread to guarantee it has stopped. ** It is possible for a thread to do an unbounded amount of computation in ** the finally's and thus indefinitely delay the threads death. ** If Abort() is called on a thread that has not been started, the thread ** will abort when Start() is called. ** If Abort is called twice on the same thread, a DuplicateThreadAbort ** exception is thrown. =========================================================================*/ [SecurityPermissionAttribute(SecurityAction.Demand, ControlThread=true)] public void Abort(Object stateInfo) { // If two aborts come at the same time, it is possible that the state info // gets set by one, and the actual abort gets delivered by another. But this // is not distinguishable by an application. // The accessor helper will only set the value if it isn't already set, // and that particular bit of native code can test much faster than this // code could, because testing might cause a cross-appdomain marshalling. AbortReason = stateInfo; // Note: we demand ControlThread permission, then call AbortInternal directly // rather than delegating to the Abort() function below. We do this to ensure // that only callers with ControlThread are allowed to change the AbortReason // of the thread. We call AbortInternal directly to avoid demanding the same // permission twice. AbortInternal(); } [SecurityPermissionAttribute(SecurityAction.Demand, ControlThread=true)] public void Abort() { AbortInternal(); } // Internal helper (since we can't place security demands on // ecalls/fcalls). [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern void AbortInternal(); /*========================================================================== ** Resets a thread abort. ** Should be called by trusted code only =========================================================================*/ [SecurityPermissionAttribute(SecurityAction.Demand, ControlThread=true)] public static void ResetAbort() { Thread thread = Thread.CurrentThread; if ((thread.ThreadState & ThreadState.AbortRequested) == 0) throw new ThreadStateException(Environment.GetResourceString("ThreadState_NoAbortRequested")); thread.ResetAbortNative(); thread.ClearAbortReason(); } [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern void ResetAbortNative(); /*========================================================================= ** Suspends the thread. If the thread is already suspended, this call has ** no effect. ** ** Exceptions: ThreadStateException if the thread has not been started or ** it is dead. =========================================================================*/ [Obsolete("Thread.Suspend has been deprecated. Please use other classes in System.Threading, such as Monitor, Mutex, Event, and Semaphore, to synchronize Threads or protect resources. http://go.microsoft.com/fwlink/?linkid=14202", false)][SecurityPermission(SecurityAction.Demand, ControlThread=true)] [SecurityPermission(SecurityAction.Demand, ControlThread=true)] public void Suspend() { SuspendInternal(); } // Internal helper (since we can't place security demands on // ecalls/fcalls). [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern void SuspendInternal(); /*========================================================================== ** Resumes a thread that has been suspended. ** ** Exceptions: ThreadStateException if the thread has not been started or ** it is dead or it isn't in the suspended state. =========================================================================*/ [Obsolete("Thread.Resume has been deprecated. Please use other classes in System.Threading, such as Monitor, Mutex, Event, and Semaphore, to synchronize Threads or protect resources. http://go.microsoft.com/fwlink/?linkid=14202", false)] [SecurityPermission(SecurityAction.Demand, ControlThread=true)] public void Resume() { ResumeInternal(); } // Internal helper (since we can't place security demands on // ecalls/fcalls). [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern void ResumeInternal(); /*========================================================================= ** Interrupts a thread that is inside a Wait(), Sleep() or Join(). If that ** thread is not currently blocked in that manner, it will be interrupted ** when it next begins to block. =========================================================================*/ [SecurityPermission(SecurityAction.Demand, ControlThread=true)] public void Interrupt() { InterruptInternal(); } // Internal helper (since we can't place security demands on // ecalls/fcalls). [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern void InterruptInternal(); /*========================================================================= ** Returns the priority of the thread. ** ** Exceptions: ThreadStateException if the thread is dead. =========================================================================*/ public ThreadPriority Priority { get { return (ThreadPriority)GetPriorityNative(); } [HostProtection(SelfAffectingThreading=true)] set { SetPriorityNative((int)value); } } [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern int GetPriorityNative(); [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern void SetPriorityNative(int priority); /*========================================================================= ** Returns true if the thread has been started and is not dead. =========================================================================*/ public bool IsAlive { get { return IsAliveNative(); } } [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern bool IsAliveNative(); /*========================================================================== ** Returns true if the thread is a threadpool thread. =========================================================================*/ public bool IsThreadPoolThread { get { return IsThreadpoolThreadNative(); } } [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern bool IsThreadpoolThreadNative(); /*========================================================================= ** Waits for the thread to die. ** ** Exceptions: ThreadInterruptedException if the thread is interrupted while waiting. ** ThreadStateException if the thread has not been started yet. =========================================================================*/ [MethodImplAttribute(MethodImplOptions.InternalCall)] [HostProtection(Synchronization=true, ExternalThreading=true)] private extern void JoinInternal(); [HostProtection(Synchronization=true, ExternalThreading=true)] public void Join() { JoinInternal(); } /*========================================================================== ** Waits for the thread to die or for timeout milliseconds to elapse. ** Returns true if the thread died, or false if the wait timed out. If ** Timeout.Infinite is given as the parameter, no timeout will occur. ** ** Exceptions: ArgumentException if timeout < 0. ** ThreadInterruptedException if the thread is interrupted while waiting. ** ThreadStateException if the thread has not been started yet. =========================================================================*/ [MethodImplAttribute(MethodImplOptions.InternalCall)] [HostProtection(Synchronization=true, ExternalThreading=true)] private extern bool JoinInternal(int millisecondsTimeout); [HostProtection(Synchronization=true, ExternalThreading=true)] public bool Join(int millisecondsTimeout) { return JoinInternal(millisecondsTimeout); } [HostProtection(Synchronization=true, ExternalThreading=true)] public bool Join(TimeSpan timeout) { long tm = (long)timeout.TotalMilliseconds; if (tm < -1 || tm > (long) Int32.MaxValue) throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); return Join((int)tm); } /*========================================================================== ** Suspends the current thread for timeout milliseconds. If timeout == 0, ** forces the thread to give up the remainer of its timeslice. If timeout ** == Timeout.Infinite, no timeout will occur. ** ** Exceptions: ArgumentException if timeout < 0. ** ThreadInterruptedException if the thread is interrupted while sleeping. =========================================================================*/ [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern void SleepInternal(int millisecondsTimeout); public static void Sleep(int millisecondsTimeout) { SleepInternal(millisecondsTimeout); } public static void Sleep(TimeSpan timeout) { long tm = (long)timeout.TotalMilliseconds; if (tm < -1 || tm > (long) Int32.MaxValue) throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); Sleep((int)tm); } /* wait for a length of time proportial to 'iterations'. Each iteration is should only take a few machine instructions. Calling this API is preferable to coding a explict busy loop because the hardware can be informed that it is busy waiting. */ [MethodImplAttribute(MethodImplOptions.InternalCall), HostProtection(Synchronization=true,ExternalThreading=true), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] private static extern void SpinWaitInternal(int iterations); [HostProtection(Synchronization=true,ExternalThreading=true), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] public static void SpinWait(int iterations) { SpinWaitInternal(iterations); } public static Thread CurrentThread { [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] get { Thread th; th = GetFastCurrentThreadNative(); if (th == null) th = GetCurrentThreadNative(); return th; } } [MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] private static extern Thread GetCurrentThreadNative(); [MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] private static extern Thread GetFastCurrentThreadNative(); private void SetStartHelper(Delegate start, int maxStackSize) { ThreadHelper threadStartCallBack = new ThreadHelper(start); if(start is ThreadStart) { SetStart(new ThreadStart(threadStartCallBack.ThreadStart), maxStackSize); } else { SetStart(new ParameterizedThreadStart(threadStartCallBack.ThreadStart), maxStackSize); } } /*========================================================================= ** PRIVATE Sets the IThreadable interface for the thread. Assumes that ** start != null. =========================================================================*/ [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern void SetStart(Delegate start, int maxStackSize); /*========================================================================== ** Clean up the thread when it goes away. =========================================================================*/ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] ~Thread() { // Delegate to the unmanaged portion. InternalFinalize(); } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern void InternalFinalize(); /*========================================================================= ** Return whether or not this thread is a background thread. Background ** threads do not affect when the Execution Engine shuts down. ** ** Exceptions: ThreadStateException if the thread is dead. =========================================================================*/ public bool IsBackground { get { return IsBackgroundNative(); } [HostProtection(SelfAffectingThreading=true)] set { SetBackgroundNative(value); } } [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern bool IsBackgroundNative(); [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern void SetBackgroundNative(bool isBackground); /*========================================================================= ** Return the thread state as a consistent set of bits. This is more ** general then IsAlive or IsBackground. =========================================================================*/ public ThreadState ThreadState { get { return (ThreadState)GetThreadStateNative(); } } [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern int GetThreadStateNative(); #if FEATURE_COMINTEROP /*========================================================================= ** An unstarted thread can be marked to indicate that it will host a ** single-threaded or multi-threaded apartment. ** ** Exceptions: ArgumentException if state is not a valid apartment state ** (ApartmentSTA or ApartmentMTA). =========================================================================*/ [Obsolete("The ApartmentState property has been deprecated. Use GetApartmentState, SetApartmentState or TrySetApartmentState instead.", false)] public ApartmentState ApartmentState { get { return (ApartmentState)GetApartmentStateNative(); } [HostProtection(Synchronization=true, SelfAffectingThreading=true)] set { SetApartmentStateNative((int)value, true); } } public ApartmentState GetApartmentState() { return (ApartmentState)GetApartmentStateNative(); } [HostProtection(Synchronization=true, SelfAffectingThreading=true)] public bool TrySetApartmentState(ApartmentState state) { return SetApartmentStateHelper(state, false); } [HostProtection(Synchronization=true, SelfAffectingThreading=true)] public void SetApartmentState(ApartmentState state) { bool result = SetApartmentStateHelper(state, true); if (!result) throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ApartmentStateSwitchFailed")); } private bool SetApartmentStateHelper(ApartmentState state, bool fireMDAOnMismatch) { ApartmentState retState = (ApartmentState)SetApartmentStateNative((int)state, fireMDAOnMismatch); // Special case where we pass in Unknown and get back MTA. // Once we CoUninitialize the thread, the OS will still // report the thread as implicitly in the MTA if any // other thread in the process is CoInitialized. if ((state == System.Threading.ApartmentState.Unknown) && (retState == System.Threading.ApartmentState.MTA)) return true; if (retState != state) return false; return true; } [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern int GetApartmentStateNative(); [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern int SetApartmentStateNative(int state, bool fireMDAOnMismatch); [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern int StartupSetApartmentStateInternal(); #endif // FEATURE_COMINTEROP /*========================================================================== ** Allocates an un-named data slot. The slot is allocated on ALL the ** threads. =========================================================================*/ [HostProtection(SharedState=true, ExternalThreading=true)] public static LocalDataStoreSlot AllocateDataSlot() { return LocalDataStoreManager.AllocateDataSlot(); } /*========================================================================= ** Allocates a named data slot. The slot is allocated on ALL the ** threads. Named data slots are "public" and can be manipulated by ** anyone. =========================================================================*/ [HostProtection(SharedState=true, ExternalThreading=true)] public static LocalDataStoreSlot AllocateNamedDataSlot(String name) { return LocalDataStoreManager.AllocateNamedDataSlot(name); } /*========================================================================== ** Looks up a named data slot. If the name has not been used, a new slot is ** allocated. Named data slots are "public" and can be manipulated by ** anyone. =========================================================================*/ [HostProtection(SharedState=true, ExternalThreading=true)] public static LocalDataStoreSlot GetNamedDataSlot(String name) { return LocalDataStoreManager.GetNamedDataSlot(name); } /*========================================================================== ** Frees a named data slot. The slot is allocated on ALL the ** threads. Named data slots are "public" and can be manipulated by ** anyone. =========================================================================*/ [HostProtection(SharedState=true, ExternalThreading=true)] public static void FreeNamedDataSlot(String name) { LocalDataStoreManager.FreeNamedDataSlot(name); } /*========================================================================= ** Retrieves the value from the specified slot on the current thread, for that thread's current domain. =========================================================================*/ [HostProtection(SharedState=true, ExternalThreading=true)] [ResourceExposure(ResourceScope.AppDomain)] public static Object GetData(LocalDataStoreSlot slot) { LocalDataStoreManager.ValidateSlot(slot); LocalDataStore dls = GetDomainLocalStore(); if (dls == null) return null; return dls.GetData(slot); } /*========================================================================== ** Sets the data in the specified slot on the currently running thread, for that thread's current domain. =========================================================================*/ [HostProtection(SharedState=true, ExternalThreading=true)] [ResourceExposure(ResourceScope.AppDomain)] public static void SetData(LocalDataStoreSlot slot, Object data) { LocalDataStore dls = GetDomainLocalStore(); // Create new DLS if one hasn't been created for this domain for this thread if (dls == null) { dls = LocalDataStoreManager.CreateLocalDataStore(); SetDomainLocalStore(dls); } dls.SetData(slot, data); } [MethodImplAttribute(MethodImplOptions.InternalCall)] [ResourceExposure(ResourceScope.AppDomain)] static extern private LocalDataStore GetDomainLocalStore(); [MethodImplAttribute(MethodImplOptions.InternalCall)] [ResourceExposure(ResourceScope.AppDomain)] static extern private void SetDomainLocalStore(LocalDataStore dls); /*** * An appdomain has been unloaded - remove its DLS from the manager */ static private void RemoveDomainLocalStore(LocalDataStore dls) { if (dls != null) LocalDataStoreManager.DeleteLocalDataStore(dls); } [MethodImplAttribute(MethodImplOptions.InternalCall)] static extern private bool nativeGetSafeCulture(Thread t, int appDomainId, bool isUI, ref CultureInfo safeCulture); // As the culture can be customized object then we cannot hold any // reference to it before we check if it is safe because the app domain // owning this customized culture may get unloaded while executing this // code. To achieve that we have to do the check using nativeGetSafeCulture // as the thread cannot get interrupted during the FCALL. // If the culture is safe (not customized or created in current app domain) // then the FCALL will return a reference to that culture otherwise the // FCALL will return failure. In case of failure we'll return the default culture. // If the app domain owning a customized culture that is set to teh thread and this // app domain get unloaded there is a code to clean up the culture from the thread // using the code in AppDomain::ReleaseDomainStores. public CultureInfo CurrentUICulture { get { // Fetch a local copy of m_CurrentUICulture to // avoid ----s that malicious user can introduce if (m_CurrentUICulture == null) { return CultureInfo.UserDefaultUICulture; } CultureInfo culture = null; if (!nativeGetSafeCulture(this, GetDomainID(), true, ref culture) || culture == null) { return CultureInfo.UserDefaultUICulture; } return culture; } [HostProtection(ExternalThreading=true)] set { if (value == null) { throw new ArgumentNullException("value"); } //If they're trying to use a Culture with a name that we can't use in resource lookup, //don't even let them set it on the thread. CultureInfo.VerifyCultureName(value, true); if (nativeSetThreadUILocale(value.LCID) == false) { throw new ArgumentException(Environment.GetResourceString("Argument_InvalidResourceCultureName", value.Name)); } value.StartCrossDomainTracking(); m_CurrentUICulture = value; } } // This returns the exposed context for a given context ID. [MethodImplAttribute(MethodImplOptions.InternalCall)] static extern private bool nativeSetThreadUILocale(int LCID); // As the culture can be customized object then we cannot hold any // reference to it before we check if it is safe because the app domain // owning this customized culture may get unloaded while executing this // code. To achieve that we have to do the check using nativeGetSafeCulture // as the thread cannot get interrupted during the FCALL. // If the culture is safe (not customized or created in current app domain) // then the FCALL will return a reference to that culture otherwise the // FCALL will return failure. In case of failure we'll return the default culture. // If the app domain owning a customized culture that is set to teh thread and this // app domain get unloaded there is a code to clean up the culture from the thread // using the code in AppDomain::ReleaseDomainStores. public CultureInfo CurrentCulture { get { // Fetch a local copy of m_CurrentCulture to // avoid ----s that malicious user can introduce if (m_CurrentCulture == null) { return CultureInfo.UserDefaultCulture; } CultureInfo culture = null; if (!nativeGetSafeCulture(this, GetDomainID(), false, ref culture) || culture == null) { return CultureInfo.UserDefaultCulture; } return culture; } [SecurityPermission(SecurityAction.Demand, ControlThread=true)] set { if (null==value) { throw new ArgumentNullException("value"); } CultureInfo.CheckNeutral(value); //If we can't set the nativeThreadLocale, we'll just let it stay //at whatever value it had before. This allows people who use //just managed code not to be limited by the underlying OS. CultureInfo.nativeSetThreadLocale(value.LCID); value.StartCrossDomainTracking(); m_CurrentCulture = value; } } /*=============================================================== ====================== Thread Statics =========================== ===============================================================*/ private int ReserveSlot() { // This is called by the thread on itself so no need for locks if (m_ThreadStaticsBuckets == null) { BCLDebug.Assert(STATICS_BUCKET_SIZE % 32 == 0,"STATICS_BUCKET_SIZE should be a multiple of 32"); // allocate bucket holder // do not publish the data until all the intialization is done, in case of asynchronized exceptions Object[][] newBuckets = new Object[1][]; SetIsThreadStaticsArray(newBuckets); // allocate the first bucket newBuckets[0] = new Object[STATICS_BUCKET_SIZE]; SetIsThreadStaticsArray(newBuckets[0]); int[] newBits = new int[newBuckets.Length*STATICS_BUCKET_SIZE/32]; // use memset! for (int i=0; i all slots occupied if (slot == 0) { // We need to expand. Allocate a new bucket int oldLength = m_ThreadStaticsBuckets.Length; int oldLengthBits = m_ThreadStaticsBits.Length; int newLength = m_ThreadStaticsBuckets.Length + 1; Object[][] newBuckets = new Object[newLength][]; SetIsThreadStaticsArray(newBuckets); int newLengthBits = newLength*STATICS_BUCKET_SIZE/32; int[] newBits = new int[newLengthBits]; // Copy old buckets into new holder Array.Copy(m_ThreadStaticsBuckets, newBuckets, m_ThreadStaticsBuckets.Length); // Allocate new buckets for (int i = oldLength ; i < newLength ; i++) { newBuckets[i] = new Object[STATICS_BUCKET_SIZE]; SetIsThreadStaticsArray(newBuckets[i]); } // Copy old bits into new bit array Array.Copy(m_ThreadStaticsBits, newBits, m_ThreadStaticsBits.Length); // Initalize new bits for(int i= oldLengthBits ; i >16)&0xffff; slot+=16; } if ((bits & 0xff) != 0) { bits = bits & 0xff; } else { slot+=8; bits = (bits>>8)&0xff; } int j; for (j=0; j<8; j++) { if ( (bits & (1< CancellationSignals { [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] get { if (m_CancellationSignals == null) { List signals = new List (); Interlocked.CompareExchange(ref m_CancellationSignals, signals, null); } return m_CancellationSignals; } } #endif /*========================================================================== ** Volatile Read & Write and MemoryBarrier methods. ** Provides the ability to read and write values ensuring that the values ** are read/written each time they are accessed. =========================================================================*/ [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static byte VolatileRead(ref byte address) { byte ret = address; MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. return ret; } [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static short VolatileRead(ref short address) { short ret = address; MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. return ret; } [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static int VolatileRead(ref int address) { int ret = address; MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. return ret; } [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static long VolatileRead(ref long address) { long ret = address; MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. return ret; } [CLSCompliant(false)] [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static sbyte VolatileRead(ref sbyte address) { sbyte ret = address; MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. return ret; } [CLSCompliant(false)] [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static ushort VolatileRead(ref ushort address) { ushort ret = address; MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. return ret; } [CLSCompliant(false)] [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static uint VolatileRead(ref uint address) { uint ret = address; MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. return ret; } [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static IntPtr VolatileRead(ref IntPtr address) { IntPtr ret = address; MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. return ret; } [CLSCompliant(false)] [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static UIntPtr VolatileRead(ref UIntPtr address) { UIntPtr ret = address; MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. return ret; } [CLSCompliant(false)] [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static ulong VolatileRead(ref ulong address) { ulong ret = address; MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. return ret; } [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static float VolatileRead(ref float address) { float ret = address; MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. return ret; } [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static double VolatileRead(ref double address) { double ret = address; MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. return ret; } [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static Object VolatileRead(ref Object address) { Object ret = address; MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. return ret; } [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static void VolatileWrite(ref byte address, byte value) { MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. address = value; } [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static void VolatileWrite(ref short address, short value) { MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. address = value; } [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static void VolatileWrite(ref int address, int value) { MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. address = value; } [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static void VolatileWrite(ref long address, long value) { MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. address = value; } [CLSCompliant(false)] [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static void VolatileWrite(ref sbyte address, sbyte value) { MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. address = value; } [CLSCompliant(false)] [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static void VolatileWrite(ref ushort address, ushort value) { MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. address = value; } [CLSCompliant(false)] [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static void VolatileWrite(ref uint address, uint value) { MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. address = value; } [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static void VolatileWrite(ref IntPtr address, IntPtr value) { MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. address = value; } [CLSCompliant(false)] [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static void VolatileWrite(ref UIntPtr address, UIntPtr value) { MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. address = value; } [CLSCompliant(false)] [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static void VolatileWrite(ref ulong address, ulong value) { MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. address = value; } [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static void VolatileWrite(ref float address, float value) { MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. address = value; } [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static void VolatileWrite(ref double address, double value) { MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. address = value; } [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static void VolatileWrite(ref Object address, Object value) { MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. address = value; } [MethodImplAttribute(MethodImplOptions.InternalCall)] public static extern void MemoryBarrier(); //We need to mark thread statics array for AppDomain leak checking purpose [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern void SetIsThreadStaticsArray(Object o); private static LocalDataStoreMgr LocalDataStoreManager { get { if (s_LocalDataStoreMgr == null) { lock(s_SyncObject) { if (s_LocalDataStoreMgr == null) s_LocalDataStoreMgr = new LocalDataStoreMgr(); } } return s_LocalDataStoreMgr; } } void _Thread.GetTypeInfoCount(out uint pcTInfo) { throw new NotImplementedException(); } void _Thread.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo) { throw new NotImplementedException(); } void _Thread.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId) { throw new NotImplementedException(); } void _Thread.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr) { throw new NotImplementedException(); } // Helper function to set the AbortReason for a thread abort. // Checks that they're not alredy set, and then atomically updates // the reason info (object + ADID). [MethodImplAttribute(MethodImplOptions.InternalCall)] internal extern void SetAbortReason(Object o); // Helper function to retrieve the AbortReason from a thread // abort. Will perform cross-AppDomain marshalling if the object // lives in a different AppDomain from the requester. [MethodImplAttribute(MethodImplOptions.InternalCall)] internal extern Object GetAbortReason(); // Helper function to clear the AbortReason. Takes care of // AppDomain related cleanup if required. [MethodImplAttribute(MethodImplOptions.InternalCall)] internal extern void ClearAbortReason(); } // End of class Thread // declaring a local var of this enum type and passing it by ref into a function that needs to do a // stack crawl will both prevent inlining of the calle and pass an ESP point to stack crawl to // Declaring these in EH clauses is illegal; they must declared in the main method body [Serializable] internal enum StackCrawlMark { LookForMe = 0, LookForMyCaller = 1, LookForMyCallersCaller = 2, LookForThread = 3 } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- UpdatePanelTriggerCollection.cs
- SafeRightsManagementHandle.cs
- dsa.cs
- LocatorManager.cs
- ContextMenu.cs
- RelationshipConverter.cs
- RestClientProxyHandler.cs
- GetPageNumberCompletedEventArgs.cs
- TabPageDesigner.cs
- GenerateScriptTypeAttribute.cs
- RestHandlerFactory.cs
- VariableQuery.cs
- TransactionWaitAsyncResult.cs
- PriorityQueue.cs
- XmlSchemaInclude.cs
- BitVec.cs
- ByteConverter.cs
- SimpleHandlerBuildProvider.cs
- RepeatBehavior.cs
- PixelFormatConverter.cs
- UTF32Encoding.cs
- ReachIDocumentPaginatorSerializerAsync.cs
- DocumentViewerBaseAutomationPeer.cs
- WindowsToolbarItemAsMenuItem.cs
- QueryContinueDragEvent.cs
- ResumeStoryboard.cs
- XpsStructure.cs
- COM2FontConverter.cs
- Viewport3DVisual.cs
- RegistryExceptionHelper.cs
- ScriptControl.cs
- PriorityBindingExpression.cs
- CfgArc.cs
- LiteralLink.cs
- PopOutPanel.cs
- PasswordRecovery.cs
- DeviceFiltersSection.cs
- Utils.cs
- NullReferenceException.cs
- ChannelManagerHelpers.cs
- WebContext.cs
- TdsParser.cs
- RightNameExpirationInfoPair.cs
- TransformDescriptor.cs
- XPathBuilder.cs
- ToolStripItem.cs
- HandlerFactoryCache.cs
- Rss20FeedFormatter.cs
- MimePart.cs
- _Semaphore.cs
- StrokeDescriptor.cs
- RegexCompiler.cs
- sapiproxy.cs
- Selector.cs
- SEHException.cs
- StringUtil.cs
- HtmlHead.cs
- InkCollectionBehavior.cs
- EventHandlers.cs
- PasswordPropertyTextAttribute.cs
- LazyTextWriterCreator.cs
- AttachmentService.cs
- SafeLibraryHandle.cs
- IndexOutOfRangeException.cs
- CodePageUtils.cs
- CloseSequenceResponse.cs
- ClickablePoint.cs
- ProjectionNode.cs
- TargetInvocationException.cs
- UxThemeWrapper.cs
- DataGridViewCellFormattingEventArgs.cs
- ExtensionQuery.cs
- DataServiceHost.cs
- ClientTarget.cs
- CollectionBuilder.cs
- PassportAuthentication.cs
- AttachedPropertyDescriptor.cs
- JumpTask.cs
- SQLDecimalStorage.cs
- WebPartMenuStyle.cs
- Sequence.cs
- Line.cs
- DataTableClearEvent.cs
- GridViewColumnCollectionChangedEventArgs.cs
- hwndwrapper.cs
- COM2Properties.cs
- DataControlCommands.cs
- AmbiguousMatchException.cs
- PtsPage.cs
- Utility.cs
- PolicyValidationException.cs
- EntityDataSourceSelectingEventArgs.cs
- OperationAbortedException.cs
- ExpressionBuilderCollection.cs
- ExitEventArgs.cs
- QueryContinueDragEvent.cs
- PolyLineSegmentFigureLogic.cs
- MemberRelationshipService.cs
- FormatSettings.cs
- DataGridViewUtilities.cs