Thread.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / clr / src / BCL / System / Threading / Thread.cs / 6 / 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 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.
// ==++== 
//
//   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

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK