The Labs \ Source Viewer \ SSCLI \ System.Threading \ ThreadHelper

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. /*=============================================================================
  16. **
  17. ** Class: Thread
  18. **
  19. **
  20. ** Purpose: Class for creating and managing a thread.
  21. **
  22. **
  23. =============================================================================*/
  24. namespace System.Threading
  25. {
  26.     using System.Threading;
  27.     using System.Runtime.InteropServices;
  28.     using System.Runtime.Remoting.Contexts;
  29.     using System.Runtime.Remoting.Messaging;
  30.     using System;
  31.     using System.Diagnostics;
  32.     using System.Security.Permissions;
  33.     using System.Security.Principal;
  34.     using System.Globalization;
  35.     using System.Collections.Generic;
  36.     using System.Runtime.Serialization;
  37.     using System.Runtime.CompilerServices;
  38.     using System.Runtime.ConstrainedExecution;
  39.     using System.Security;
  40.     using System.Runtime.Versioning;
  41.    
  42.     internal delegate object InternalCrossContextDelegate(object[] args);
  43.    
  44.     internal class ThreadHelper
  45.     {
  46.         Delegate _start;
  47.         object _startArg = null;
  48.         ExecutionContext _executionContext = null;
  49.         internal ThreadHelper(Delegate start)
  50.         {
  51.             _start = start;
  52.         }
  53.        
  54.         internal void SetExecutionContextHelper(ExecutionContext ec)
  55.         {
  56.             _executionContext = ec;
  57.         }
  58.         static internal ContextCallback _ccb = new ContextCallback(ThreadStart_Context);
  59.         static internal void ThreadStart_Context(object state)
  60.         {
  61.             ThreadHelper t = (ThreadHelper)state;
  62.             if (t._start is ThreadStart) {
  63.                 ((ThreadStart)t._start)();
  64.             }
  65.             else {
  66.                 ((ParameterizedThreadStart)t._start)(t._startArg);
  67.             }
  68.         }
  69.        
  70.         // call back helper
  71.         internal void ThreadStart(object obj)
  72.         {
  73.             _startArg = obj;
  74.             if (_executionContext != null) {
  75.                 ExecutionContext.Run(_executionContext, _ccb, (object)this);
  76.             }
  77.             else {
  78.                 ((ParameterizedThreadStart)_start)(obj);
  79.             }
  80.         }
  81.        
  82.         // call back helper
  83.         internal void ThreadStart()
  84.         {
  85.             if (_executionContext != null) {
  86.                 ExecutionContext.Run(_executionContext, _ccb, (object)this);
  87.             }
  88.             else {
  89.                 ((ThreadStart)_start)();
  90.             }
  91.         }
  92.     }
  93.    
  94.     // deliberately not [serializable]
  95.     [ClassInterface(ClassInterfaceType.None)]
  96.     [ComDefaultInterface(typeof(_Thread))]
  97.     [System.Runtime.InteropServices.ComVisible(true)]
  98.     public sealed class Thread : CriticalFinalizerObject, _Thread
  99.     {
  100. /*=========================================================================
  101.         ** Data accessed from managed code that needs to be defined in
  102.         ** ThreadBaseObject to maintain alignment between the two classes.
  103.         ** DON'T CHANGE THESE UNLESS YOU MODIFY ThreadBaseObject in vm\object.h
  104.         =========================================================================*/       
  105.         private Context m_Context;
  106.        
  107.         private ExecutionContext m_ExecutionContext;
  108.         // this call context follows the logical thread
  109.         private string m_Name;
  110.         private Delegate m_Delegate;
  111.         // Delegate
  112.         private object[][] m_ThreadStaticsBuckets;
  113.         // Holder for thread statics
  114.         private int[] m_ThreadStaticsBits;
  115.         // Bit-markers for slot availability
  116.         private CultureInfo m_CurrentCulture;
  117.         private CultureInfo m_CurrentUICulture;
  118.         private object m_ThreadStartArg;
  119.        
  120. /*=========================================================================
  121.         ** The base implementation of Thread is all native.  The following fields
  122.         ** should never be used in the C# code.  They are here to define the proper
  123.         ** space so the thread object may be allocated.  DON'T CHANGE THESE UNLESS
  124.         ** YOU MODIFY ThreadBaseObject in vm\object.h
  125.         =========================================================================*/       
  126.         #pragma warning disable 169
  127.         #pragma warning disable 414 // These fields are not used from managed.
  128.         // IntPtrs need to be together, and before ints, because IntPtrs are 64-bit
  129.         // fields on 64-bit platforms, where they will be sorted together.
  130.        
  131.         private IntPtr DONT_USE_InternalThread;
  132.         // Pointer
  133.         private int m_Priority;
  134.         // INT32
  135.         #pragma warning restore 414
  136.         #pragma warning restore 169
  137. /*=========================================================================
  138.         ** This manager is responsible for storing the global data that is
  139.         ** shared amongst all the thread local stores.
  140.         =========================================================================*/       
  141.         private static LocalDataStoreMgr s_LocalDataStoreMgr = null;
  142.         private static object s_SyncObject = new object();
  143.        
  144.         // Has to be in sync with THREAD_STATICS_BUCKET_SIZE in vm/threads.cpp
  145.         private const int STATICS_BUCKET_SIZE = 32;
  146.        
  147. /*=========================================================================
  148.         ** Creates a new Thread object which will begin execution at
  149.         ** start.ThreadStart on a new thread when the Start method is called.
  150.         **
  151.         ** Exceptions: ArgumentNullException if start == null.
  152.         =========================================================================*/       
  153.         public Thread(ThreadStart start)
  154.         {
  155.             if (start == null) {
  156.                 throw new ArgumentNullException("start");
  157.             }
  158.             SetStartHelper((Delegate)start, 0);
  159.             //0 will setup Thread with default stackSize
  160.         }
  161.        
  162.         public Thread(ThreadStart start, int maxStackSize)
  163.         {
  164.             if (start == null) {
  165.                 throw new ArgumentNullException("start");
  166.             }
  167.             if (0 > maxStackSize)
  168.                 throw new ArgumentOutOfRangeException("maxStackSize", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
  169.             SetStartHelper((Delegate)start, maxStackSize);
  170.         }
  171.         public Thread(ParameterizedThreadStart start)
  172.         {
  173.             if (start == null) {
  174.                 throw new ArgumentNullException("start");
  175.             }
  176.             SetStartHelper((Delegate)start, 0);
  177.         }
  178.        
  179.         public Thread(ParameterizedThreadStart start, int maxStackSize)
  180.         {
  181.             if (start == null) {
  182.                 throw new ArgumentNullException("start");
  183.             }
  184.             if (0 > maxStackSize)
  185.                 throw new ArgumentOutOfRangeException("maxStackSize", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
  186.             SetStartHelper((Delegate)start, maxStackSize);
  187.         }
  188.        
  189.         [ComVisible(false), MethodImplAttribute(MethodImplOptions.InternalCall)]
  190.         public override extern int GetHashCode();
  191.        
  192.         public extern int ManagedThreadId {
  193.             [MethodImplAttribute(MethodImplOptions.InternalCall)]
  194.             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
  195.             get;
  196.         }
  197.        
  198. /*=========================================================================
  199.         ** Spawns off a new thread which will begin executing at the ThreadStart
  200.         ** method on the IThreadable interface passed in the constructor. Once the
  201.         ** thread is dead, it cannot be restarted with another call to Start.
  202.         **
  203.         ** Exceptions: ThreadStateException if the thread has already been started.
  204.         =========================================================================*/       
  205.         [HostProtection(Synchronization = true, ExternalThreading = true)]
  206.         public void Start()
  207.         {
  208.            
  209.             // Attach current thread's security principal object to the new
  210.             // thread. Be careful not to bind the current thread to a principal
  211.             // if it's not already bound.
  212.             if (m_Delegate != null) {
  213.                 ThreadHelper t = (ThreadHelper)(m_Delegate.Target);
  214.                 ExecutionContext ec = ExecutionContext.Capture();
  215.                 ExecutionContext.ClearSyncContext(ec);
  216.                 t.SetExecutionContextHelper(ec);
  217.             }
  218.             IPrincipal principal = (IPrincipal)CallContext.Principal;
  219.             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
  220.             StartInternal(principal, ref stackMark);
  221.         }
  222.        
  223.         [HostProtection(Synchronization = true, ExternalThreading = true)]
  224.         public void Start(object parameter)
  225.         {
  226.             //In the case of a null delegate (second call to start on same thread)
  227.             // StartInternal method will take care of the error reporting
  228.             if (m_Delegate is ThreadStart) {
  229.                 //We expect the thread to be setup with a ParameterizedThreadStart
  230.                 // if this constructor is called.
  231.                 //If we got here then that wasn't the case
  232.                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ThreadWrongThreadStart"));
  233.             }
  234.             m_ThreadStartArg = parameter;
  235.             Start();
  236.         }
  237.        
  238.         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
  239.         internal ExecutionContext GetExecutionContextNoCreate()
  240.         {
  241.             return m_ExecutionContext;
  242.         }
  243.        
  244.        
  245.        
  246.         public ExecutionContext ExecutionContext {
  247.             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
  248.             get {
  249.                 if (m_ExecutionContext == null && this == Thread.CurrentThread) {
  250.                     m_ExecutionContext = new ExecutionContext();
  251.                     m_ExecutionContext.Thread = this;
  252.                 }
  253.                 return m_ExecutionContext;
  254.             }
  255.         }
  256.        
  257.         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
  258.         internal void SetExecutionContext(ExecutionContext value)
  259.         {
  260.             m_ExecutionContext = value;
  261.             if (value != null)
  262.                 m_ExecutionContext.Thread = this;
  263.         }
  264.        
  265.        
  266.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  267.         private extern void StartInternal(IPrincipal principal, ref StackCrawlMark stackMark);
  268.        
  269.         /// <internalonly/>
  270.         [StrongNameIdentityPermissionAttribute(SecurityAction.LinkDemand, PublicKey = "0x00000000000000000400000000000000"), SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode), DynamicSecurityMethodAttribute()]
  271.         [Obsolete("Thread.SetCompressedStack is no longer supported. Please use the System.Threading.CompressedStack class")]
  272.         public void SetCompressedStack(CompressedStack stack)
  273.         {
  274.             throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ThreadAPIsNotSupported"));
  275.         }
  276.        
  277.         [MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
  278.         internal extern IntPtr SetAppDomainStack(SafeCompressedStackHandle csHandle);
  279.        
  280.         [MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
  281.         internal extern void RestoreAppDomainStack(IntPtr appDomainStack);
  282.        
  283.        
  284.         /// <internalonly/>
  285.         [StrongNameIdentityPermissionAttribute(SecurityAction.LinkDemand, PublicKey = "0x00000000000000000400000000000000"), SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
  286.         [Obsolete("Thread.GetCompressedStack is no longer supported. Please use the System.Threading.CompressedStack class")]
  287.         public CompressedStack GetCompressedStack()
  288.         {
  289.             throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ThreadAPIsNotSupported"));
  290.         }
  291.        
  292.        
  293.         // Helper method to get a logical thread ID for StringBuilder (for
  294.         // correctness) and for FileStream's async code path (for perf, to
  295.         // avoid creating a Thread instance).
  296.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  297.         static internal extern IntPtr InternalGetCurrentThread();
  298.        
  299. /*=========================================================================
  300.         ** Raises a ThreadAbortException in the thread, which usually
  301.         ** results in the thread's death. The ThreadAbortException is a special
  302.         ** exception that is not catchable. The finally clauses of all try
  303.         ** statements will be executed before the thread dies. This includes the
  304.         ** finally that a thread might be executing at the moment the Abort is raised.
  305.         ** The thread is not stopped immediately--you must Join on the
  306.         ** thread to guarantee it has stopped.
  307.         ** It is possible for a thread to do an unbounded amount of computation in
  308.         ** the finally's and thus indefinitely delay the threads death.
  309.         ** If Abort() is called on a thread that has not been started, the thread
  310.         ** will abort when Start() is called.
  311.         ** If Abort is called twice on the same thread, a DuplicateThreadAbort
  312.         ** exception is thrown.
  313.         =========================================================================*/       
  314.        
  315.         [SecurityPermissionAttribute(SecurityAction.Demand, ControlThread = true)]
  316.         public void Abort(object stateInfo)
  317.         {
  318.             // If two aborts come at the same time, it is possible that the state info
  319.             // gets set by one, and the actual abort gets delivered by another. But this
  320.             // is not distinguishable by an application.
  321.             // The accessor helper will only set the value if it isn't already set,
  322.             // and that particular bit of native code can test much faster than this
  323.             // code could, because testing might cause a cross-appdomain marshalling.
  324.             AbortReason = stateInfo;
  325.            
  326.             // Note: we demand ControlThread permission, then call AbortInternal directly
  327.             // rather than delegating to the Abort() function below. We do this to ensure
  328.             // that only callers with ControlThread are allowed to change the AbortReason
  329.             // of the thread. We call AbortInternal directly to avoid demanding the same
  330.             // permission twice.
  331.             AbortInternal();
  332.         }
  333.        
  334.         [SecurityPermissionAttribute(SecurityAction.Demand, ControlThread = true)]
  335.         public void Abort()
  336.         {
  337.             AbortInternal();
  338.         }
  339.        
  340.         // Internal helper (since we can't place security demands on
  341.         // ecalls/fcalls).
  342.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  343.         private extern void AbortInternal();
  344.        
  345. /*=========================================================================
  346.         ** Resets a thread abort.
  347.         ** Should be called by trusted code only
  348.           =========================================================================*/       
  349.         [SecurityPermissionAttribute(SecurityAction.Demand, ControlThread = true)]
  350.         public static void ResetAbort()
  351.         {
  352.             Thread thread = Thread.CurrentThread;
  353.             if ((thread.ThreadState & ThreadState.AbortRequested) == 0)
  354.                 throw new ThreadStateException(Environment.GetResourceString("ThreadState_NoAbortRequested"));
  355.             thread.ResetAbortNative();
  356.             thread.ClearAbortReason();
  357.         }
  358.        
  359.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  360.         private extern void ResetAbortNative();
  361.        
  362. /*=========================================================================
  363.         ** Suspends the thread. If the thread is already suspended, this call has
  364.         ** no effect.
  365.         **
  366.         ** Exceptions: ThreadStateException if the thread has not been started or
  367.         **            it is dead.
  368.         =========================================================================*/       
  369.         [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)]
  370.         [SecurityPermission(SecurityAction.Demand, ControlThread = true)]
  371.         [SecurityPermission(SecurityAction.Demand, ControlThread = true)]
  372.         public void Suspend()
  373.         {
  374.             SuspendInternal();
  375.         }
  376.        
  377.         // Internal helper (since we can't place security demands on
  378.         // ecalls/fcalls).
  379.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  380.         private extern void SuspendInternal();
  381.        
  382. /*=========================================================================
  383.         ** Resumes a thread that has been suspended.
  384.         **
  385.         ** Exceptions: ThreadStateException if the thread has not been started or
  386.         **            it is dead or it isn't in the suspended state.
  387.         =========================================================================*/       
  388.         [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)]
  389.         [SecurityPermission(SecurityAction.Demand, ControlThread = true)]
  390.         public void Resume()
  391.         {
  392.             ResumeInternal();
  393.         }
  394.        
  395.         // Internal helper (since we can't place security demands on
  396.         // ecalls/fcalls).
  397.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  398.         private extern void ResumeInternal();
  399.        
  400. /*=========================================================================
  401.         ** Interrupts a thread that is inside a Wait(), Sleep() or Join().  If that
  402.         ** thread is not currently blocked in that manner, it will be interrupted
  403.         ** when it next begins to block.
  404.         =========================================================================*/       
  405.         [SecurityPermission(SecurityAction.Demand, ControlThread = true)]
  406.         public void Interrupt()
  407.         {
  408.             InterruptInternal();
  409.         }
  410.        
  411.         // Internal helper (since we can't place security demands on
  412.         // ecalls/fcalls).
  413.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  414.         private extern void InterruptInternal();
  415.        
  416. /*=========================================================================
  417.         ** Returns the priority of the thread.
  418.         **
  419.         ** Exceptions: ThreadStateException if the thread is dead.
  420.         =========================================================================*/       
  421.         public ThreadPriority Priority {
  422.             get { return (ThreadPriority)GetPriorityNative(); }
  423.             [HostProtection(SelfAffectingThreading = true)]
  424.             set { SetPriorityNative((int)value); }
  425.         }
  426.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  427.         private extern int GetPriorityNative();
  428.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  429.         private extern void SetPriorityNative(int priority);
  430.        
  431. /*=========================================================================
  432.         ** Returns true if the thread has been started and is not dead.
  433.         =========================================================================*/       
  434.         public bool IsAlive {
  435.             get { return IsAliveNative(); }
  436.         }
  437.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  438.         private extern bool IsAliveNative();
  439.        
  440. /*=========================================================================
  441.         ** Returns true if the thread is a threadpool thread.
  442.         =========================================================================*/       
  443.         public bool IsThreadPoolThread {
  444.             get { return IsThreadpoolThreadNative(); }
  445.         }
  446.        
  447.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  448.         private extern bool IsThreadpoolThreadNative();
  449.        
  450. /*=========================================================================
  451.         ** Waits for the thread to die.
  452.         **
  453.         ** Exceptions: ThreadInterruptedException if the thread is interrupted while waiting.
  454.         **            ThreadStateException if the thread has not been started yet.
  455.         =========================================================================*/       
  456.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  457.         [HostProtection(Synchronization = true, ExternalThreading = true)]
  458.         private extern void JoinInternal();
  459.        
  460.         [HostProtection(Synchronization = true, ExternalThreading = true)]
  461.         public void Join()
  462.         {
  463.             JoinInternal();
  464.         }
  465.        
  466. /*=========================================================================
  467.         ** Waits for the thread to die or for timeout milliseconds to elapse.
  468.         ** Returns true if the thread died, or false if the wait timed out. If
  469.         ** Timeout.Infinite is given as the parameter, no timeout will occur.
  470.         **
  471.         ** Exceptions: ArgumentException if timeout < 0.
  472.         **            ThreadInterruptedException if the thread is interrupted while waiting.
  473.         **            ThreadStateException if the thread has not been started yet.
  474.         =========================================================================*/       
  475.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  476.         [HostProtection(Synchronization = true, ExternalThreading = true)]
  477.         private extern bool JoinInternal(int millisecondsTimeout);
  478.        
  479.         [HostProtection(Synchronization = true, ExternalThreading = true)]
  480.         public bool Join(int millisecondsTimeout)
  481.         {
  482.             return JoinInternal(millisecondsTimeout);
  483.         }
  484.        
  485.         [HostProtection(Synchronization = true, ExternalThreading = true)]
  486.         public bool Join(TimeSpan timeout)
  487.         {
  488.             long tm = (long)timeout.TotalMilliseconds;
  489.             if (tm < -1 || tm > (long)Int32.MaxValue)
  490.                 throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
  491.            
  492.             return Join((int)tm);
  493.         }
  494.        
  495. /*=========================================================================
  496.         ** Suspends the current thread for timeout milliseconds. If timeout == 0,
  497.         ** forces the thread to give up the remainer of its timeslice.  If timeout
  498.         ** == Timeout.Infinite, no timeout will occur.
  499.         **
  500.         ** Exceptions: ArgumentException if timeout < 0.
  501.         **            ThreadInterruptedException if the thread is interrupted while sleeping.
  502.         =========================================================================*/       
  503.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  504.         private static extern void SleepInternal(int millisecondsTimeout);
  505.        
  506.         public static void Sleep(int millisecondsTimeout)
  507.         {
  508.             SleepInternal(millisecondsTimeout);
  509.         }
  510.        
  511.         public static void Sleep(TimeSpan timeout)
  512.         {
  513.             long tm = (long)timeout.TotalMilliseconds;
  514.             if (tm < -1 || tm > (long)Int32.MaxValue)
  515.                 throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
  516.             Sleep((int)tm);
  517.         }
  518.        
  519.        
  520. /* wait for a length of time proportial to 'iterations'.  Each iteration is should
  521.           only take a few machine instructions.  Calling this API is preferable to coding
  522.           a explict busy loop because the hardware can be informed that it is busy waiting. */       
  523.        
  524.         [MethodImplAttribute(MethodImplOptions.InternalCall), HostProtection(Synchronization = true, ExternalThreading = true), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
  525.         private static extern void SpinWaitInternal(int iterations);
  526.        
  527.         [HostProtection(Synchronization = true, ExternalThreading = true), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
  528.         public static void SpinWait(int iterations)
  529.         {
  530.             SpinWaitInternal(iterations);
  531.         }
  532.        
  533.        
  534.         public static Thread CurrentThread {
  535.             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
  536.             get {
  537.                 Thread th;
  538.                 th = GetFastCurrentThreadNative();
  539.                 if (th == null)
  540.                     th = GetCurrentThreadNative();
  541.                 return th;
  542.             }
  543.         }
  544.         [MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
  545.         private static extern Thread GetCurrentThreadNative();
  546.         [MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
  547.         private static extern Thread GetFastCurrentThreadNative();
  548.        
  549.         private void SetStartHelper(Delegate start, int maxStackSize)
  550.         {
  551.             ThreadHelper threadStartCallBack = new ThreadHelper(start);
  552.             if (start is ThreadStart) {
  553.                 SetStart(new ThreadStart(threadStartCallBack.ThreadStart), maxStackSize);
  554.             }
  555.             else {
  556.                 SetStart(new ParameterizedThreadStart(threadStartCallBack.ThreadStart), maxStackSize);
  557.             }
  558.         }
  559.        
  560. /*=========================================================================
  561.         ** PRIVATE Sets the IThreadable interface for the thread. Assumes that
  562.         ** start != null.
  563.         =========================================================================*/       
  564.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  565.         private extern void SetStart(Delegate start, int maxStackSize);
  566.        
  567. /*=========================================================================
  568.         ** Clean up the thread when it goes away.
  569.         =========================================================================*/       
  570.         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
  571.         ~Thread()
  572.         {
  573.             // Delegate to the unmanaged portion.
  574.             InternalFinalize();
  575.         }
  576.        
  577.         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
  578.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  579.         private extern void InternalFinalize();
  580.        
  581.        
  582. /*=========================================================================
  583.         ** Return whether or not this thread is a background thread.  Background
  584.         ** threads do not affect when the Execution Engine shuts down.
  585.         **
  586.         ** Exceptions: ThreadStateException if the thread is dead.
  587.         =========================================================================*/       
  588.         public bool IsBackground {
  589.             get { return IsBackgroundNative(); }
  590.             [HostProtection(SelfAffectingThreading = true)]
  591.             set { SetBackgroundNative(value); }
  592.         }
  593.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  594.         private extern bool IsBackgroundNative();
  595.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  596.         private extern void SetBackgroundNative(bool isBackground);
  597.        
  598.        
  599. /*=========================================================================
  600.         ** Return the thread state as a consistent set of bits.  This is more
  601.         ** general then IsAlive or IsBackground.
  602.         =========================================================================*/       
  603.         public ThreadState ThreadState {
  604.             get { return (ThreadState)GetThreadStateNative(); }
  605.         }
  606.        
  607.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  608.         private extern int GetThreadStateNative();
  609.        
  610.        
  611. /*=========================================================================
  612.         ** Allocates an un-named data slot. The slot is allocated on ALL the
  613.         ** threads.
  614.         =========================================================================*/       
  615.         [HostProtection(SharedState = true, ExternalThreading = true)]
  616.         public static LocalDataStoreSlot AllocateDataSlot()
  617.         {
  618.             return LocalDataStoreManager.AllocateDataSlot();
  619.         }
  620.        
  621. /*=========================================================================
  622.         ** Allocates a named data slot. The slot is allocated on ALL the
  623.         ** threads.  Named data slots are "public" and can be manipulated by
  624.         ** anyone.
  625.         =========================================================================*/       
  626.         [HostProtection(SharedState = true, ExternalThreading = true)]
  627.         public static LocalDataStoreSlot AllocateNamedDataSlot(string name)
  628.         {
  629.             return LocalDataStoreManager.AllocateNamedDataSlot(name);
  630.         }
  631.        
  632. /*=========================================================================
  633.         ** Looks up a named data slot. If the name has not been used, a new slot is
  634.         ** allocated.  Named data slots are "public" and can be manipulated by
  635.         ** anyone.
  636.         =========================================================================*/       
  637.         [HostProtection(SharedState = true, ExternalThreading = true)]
  638.         public static LocalDataStoreSlot GetNamedDataSlot(string name)
  639.         {
  640.             return LocalDataStoreManager.GetNamedDataSlot(name);
  641.         }
  642.        
  643. /*=========================================================================
  644.         ** Frees a named data slot. The slot is allocated on ALL the
  645.         ** threads.  Named data slots are "public" and can be manipulated by
  646.         ** anyone.
  647.         =========================================================================*/       
  648.         [HostProtection(SharedState = true, ExternalThreading = true)]
  649.         public static void FreeNamedDataSlot(string name)
  650.         {
  651.             LocalDataStoreManager.FreeNamedDataSlot(name);
  652.         }
  653.        
  654. /*=========================================================================
  655.         ** Retrieves the value from the specified slot on the current thread, for that thread's current domain.
  656.         =========================================================================*/       
  657.         [HostProtection(SharedState = true, ExternalThreading = true)]
  658.         [ResourceExposure(ResourceScope.AppDomain)]
  659.         public static object GetData(LocalDataStoreSlot slot)
  660.         {
  661.             LocalDataStoreManager.ValidateSlot(slot);
  662.            
  663.             LocalDataStore dls = GetDomainLocalStore();
  664.             if (dls == null)
  665.                 return null;
  666.            
  667.             return dls.GetData(slot);
  668.         }
  669.        
  670. /*=========================================================================
  671.         ** Sets the data in the specified slot on the currently running thread, for that thread's current domain.
  672.         =========================================================================*/       
  673.         [HostProtection(SharedState = true, ExternalThreading = true)]
  674.         [ResourceExposure(ResourceScope.AppDomain)]
  675.         public static void SetData(LocalDataStoreSlot slot, object data)
  676.         {
  677.             LocalDataStore dls = GetDomainLocalStore();
  678.            
  679.             // Create new DLS if one hasn't been created for this domain for this thread
  680.             if (dls == null) {
  681.                 dls = LocalDataStoreManager.CreateLocalDataStore();
  682.                 SetDomainLocalStore(dls);
  683.             }
  684.            
  685.             dls.SetData(slot, data);
  686.         }
  687.        
  688.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  689.         [ResourceExposure(ResourceScope.AppDomain)]
  690.         private static extern LocalDataStore GetDomainLocalStore();
  691.        
  692.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  693.         [ResourceExposure(ResourceScope.AppDomain)]
  694.         private static extern void SetDomainLocalStore(LocalDataStore dls);
  695.        
  696. /***
  697.         * An appdomain has been unloaded - remove its DLS from the manager
  698.         */       
  699.         private static void RemoveDomainLocalStore(LocalDataStore dls)
  700.         {
  701.             if (dls != null)
  702.                 LocalDataStoreManager.DeleteLocalDataStore(dls);
  703.         }
  704.        
  705.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  706.         private static extern bool nativeGetSafeCulture(Thread t, int appDomainId, bool isUI, ref CultureInfo safeCulture);
  707.        
  708.         // As the culture can be customized object then we cannot hold any
  709.         // reference to it before we check if it is safe because the app domain
  710.         // owning this customized culture may get unloaded while executing this
  711.         // code. To achieve that we have to do the check using nativeGetSafeCulture
  712.         // as the thread cannot get interrupted during the FCALL.
  713.         // If the culture is safe (not customized or created in current app domain)
  714.         // then the FCALL will return a reference to that culture otherwise the
  715.         // FCALL will return failure. In case of failure we'll return the default culture.
  716.         // If the app domain owning a customized culture that is set to teh thread and this
  717.         // app domain get unloaded there is a code to clean up the culture from the thread
  718.         // using the code in AppDomain::ReleaseDomainStores.
  719.        
  720.         public CultureInfo CurrentUICulture {
  721.             get {
  722.                 // Fetch a local copy of m_CurrentUICulture to
  723.                 // avoid races that malicious user can introduce
  724.                 if (m_CurrentUICulture == null) {
  725.                     return CultureInfo.UserDefaultUICulture;
  726.                 }
  727.                
  728.                 CultureInfo culture = null;
  729.                
  730.                 if (!nativeGetSafeCulture(this, GetDomainID(), true, ref culture) || culture == null) {
  731.                     return CultureInfo.UserDefaultUICulture;
  732.                 }
  733.                
  734.                 return culture;
  735.             }
  736.            
  737.             [HostProtection(ExternalThreading = true)]
  738.             set {
  739.                 if (value == null) {
  740.                     throw new ArgumentNullException("value");
  741.                 }
  742.                
  743.                 //If they're trying to use a Culture with a name that we can't use in resource lookup,
  744.                 //don't even let them set it on the thread.
  745.                 CultureInfo.VerifyCultureName(value, true);
  746.                
  747.                 if (nativeSetThreadUILocale(value.LCID) == false) {
  748.                     throw new ArgumentException(Environment.GetResourceString("Argument_InvalidResourceCultureName", value.Name));
  749.                 }
  750.                
  751.                 value.StartCrossDomainTracking();
  752.                 m_CurrentUICulture = value;
  753.             }
  754.         }
  755.        
  756.         // This returns the exposed context for a given context ID.
  757.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  758.         private static extern bool nativeSetThreadUILocale(int LCID);
  759.        
  760.         // As the culture can be customized object then we cannot hold any
  761.         // reference to it before we check if it is safe because the app domain
  762.         // owning this customized culture may get unloaded while executing this
  763.         // code. To achieve that we have to do the check using nativeGetSafeCulture
  764.         // as the thread cannot get interrupted during the FCALL.
  765.         // If the culture is safe (not customized or created in current app domain)
  766.         // then the FCALL will return a reference to that culture otherwise the
  767.         // FCALL will return failure. In case of failure we'll return the default culture.
  768.         // If the app domain owning a customized culture that is set to teh thread and this
  769.         // app domain get unloaded there is a code to clean up the culture from the thread
  770.         // using the code in AppDomain::ReleaseDomainStores.
  771.        
  772.         public CultureInfo CurrentCulture {
  773.             get {
  774.                 // Fetch a local copy of m_CurrentCulture to
  775.                 // avoid races that malicious user can introduce
  776.                 if (m_CurrentCulture == null) {
  777.                     return CultureInfo.UserDefaultCulture;
  778.                 }
  779.                
  780.                 CultureInfo culture = null;
  781.                
  782.                 if (!nativeGetSafeCulture(this, GetDomainID(), false, ref culture) || culture == null) {
  783.                     return CultureInfo.UserDefaultCulture;
  784.                 }
  785.                
  786.                 return culture;
  787.             }
  788.            
  789.             [SecurityPermission(SecurityAction.Demand, ControlThread = true)]
  790.             set {
  791.                 if (null == value) {
  792.                     throw new ArgumentNullException("value");
  793.                 }
  794.                 CultureInfo.CheckNeutral(value);
  795.                
  796.                 //If we can't set the nativeThreadLocale, we'll just let it stay
  797.                 //at whatever value it had before. This allows people who use
  798.                 //just managed code not to be limited by the underlying OS.
  799.                 CultureInfo.nativeSetThreadLocale(value.LCID);
  800.                
  801.                 value.StartCrossDomainTracking();
  802.                 m_CurrentCulture = value;
  803.             }
  804.         }
  805.        
  806. /*===============================================================
  807.         ====================== Thread Statics ===========================
  808.         ===============================================================*/       
  809.         private int ReserveSlot()
  810.         {
  811.             // This is called by the thread on itself so no need for locks
  812.             if (m_ThreadStaticsBuckets == null) {
  813.                 BCLDebug.Assert(STATICS_BUCKET_SIZE % 32 == 0, "STATICS_BUCKET_SIZE should be a multiple of 32");
  814.                
  815.                 // allocate bucket holder
  816.                 // do not publish the data until all the intialization is done, in case of asynchronized exceptions
  817.                 object[][] newBuckets = new object[1][];
  818.                 SetIsThreadStaticsArray(newBuckets);
  819.                
  820.                 // allocate the first bucket
  821.                 newBuckets[0] = new object[STATICS_BUCKET_SIZE];
  822.                 SetIsThreadStaticsArray(newBuckets[0]);
  823.                
  824.                 int[] newBits = new int[newBuckets.Length * STATICS_BUCKET_SIZE / 32];
  825.                
  826.                 // use memset!
  827.                 for (int i = 0; i < newBits.Length; i++) {
  828.                     newBits[i] = unchecked((int)4294967295u);
  829.                 }
  830.                
  831.                 // block the 0th position, we don't want any static to have
  832.                 // slot #0 (we use it to indicate invalid slot)
  833.                 newBits[0] &= ~1;
  834.                
  835.                 // also we clear the bit for slot #1, as that is the one we will be returning
  836.                 newBits[0] &= ~2;
  837.                
  838.                 // now publish the arrays
  839.                 // the write order matters here, because we check m_ThreadStaticsBuckets for initialization,
  840.                 // we should write it at the last
  841.                 m_ThreadStaticsBits = newBits;
  842.                 m_ThreadStaticsBuckets = newBuckets;
  843.                
  844.                 return 1;
  845.             }
  846.             int slot = FindSlot();
  847.            
  848.             // slot == 0 => all slots occupied
  849.             if (slot == 0) {
  850.                 // We need to expand. Allocate a new bucket
  851.                 int oldLength = m_ThreadStaticsBuckets.Length;
  852.                 int oldLengthBits = m_ThreadStaticsBits.Length;
  853.                
  854.                 int newLength = m_ThreadStaticsBuckets.Length + 1;
  855.                 object[][] newBuckets = new object[newLength][];
  856.                 SetIsThreadStaticsArray(newBuckets);
  857.                
  858.                 int newLengthBits = newLength * STATICS_BUCKET_SIZE / 32;
  859.                 int[] newBits = new int[newLengthBits];
  860.                
  861.                 // Copy old buckets into new holder
  862.                 Array.Copy(m_ThreadStaticsBuckets, newBuckets, m_ThreadStaticsBuckets.Length);
  863.                
  864.                 // Allocate new buckets
  865.                 for (int i = oldLength; i < newLength; i++) {
  866.                     newBuckets[i] = new object[STATICS_BUCKET_SIZE];
  867.                     SetIsThreadStaticsArray(newBuckets[i]);
  868.                 }
  869.                
  870.                
  871.                 // Copy old bits into new bit array
  872.                 Array.Copy(m_ThreadStaticsBits, newBits, m_ThreadStaticsBits.Length);
  873.                
  874.                 // Initalize new bits
  875.                 for (int i = oldLengthBits; i < newLengthBits; i++) {
  876.                     newBits[i] = unchecked((int)4294967295u);
  877.                 }
  878.                
  879.                 // Return the first slot in the expanded area
  880.                 newBits[oldLengthBits] &= ~1;
  881.                
  882.                 // warning: if exceptions happen between the two writes, we are in a corrupted state
  883.                 // but the chances are very low
  884.                 m_ThreadStaticsBits = newBits;
  885.                 m_ThreadStaticsBuckets = newBuckets;
  886.                
  887.                 return oldLength * STATICS_BUCKET_SIZE;
  888.             }
  889.             return slot;
  890.         }
  891.        
  892.         int FindSlot()
  893.         {
  894.             #if DEBUG
  895.             BCLDebug.Assert(m_ThreadStaticsBits != null, "m_ThreadStaticsBits must already be initialized");
  896.             if (m_ThreadStaticsBits.Length != 0) {
  897.                 BCLDebug.Assert(m_ThreadStaticsBuckets != null && m_ThreadStaticsBits.Length == m_ThreadStaticsBuckets.Length * STATICS_BUCKET_SIZE / 32, "m_ThreadStaticsBuckets must already be intialized");
  898.                 for (int j = 0; j < m_ThreadStaticsBuckets.Length; j++) {
  899.                     BCLDebug.Assert(m_ThreadStaticsBuckets[j] != null && m_ThreadStaticsBuckets[j].Length == STATICS_BUCKET_SIZE, "m_ThreadStaticsBuckets must already be initialized");
  900.                 }
  901.             }
  902.             #endif //DEBUG
  903.            
  904.             int slot = 0;
  905.             // 0 is not a valid slot number
  906.             int bits = 0;
  907.             int i;
  908.             bool bFound = false;
  909.            
  910.             if (m_ThreadStaticsBits.Length != 0 && m_ThreadStaticsBits.Length != m_ThreadStaticsBuckets.Length * STATICS_BUCKET_SIZE / 32)
  911.                 return 0;
  912.            
  913.             for (i = 0; i < m_ThreadStaticsBits.Length; i++) {
  914.                 bits = m_ThreadStaticsBits[i];
  915.                 if (bits != 0) {
  916.                     if ((bits & 65535) != 0) {
  917.                         bits = bits & 65535;
  918.                     }
  919.                     else {
  920.                         bits = (bits >> 16) & 65535;
  921.                         slot += 16;
  922.                     }
  923.                     if ((bits & 255) != 0) {
  924.                         bits = bits & 255;
  925.                     }
  926.                     else {
  927.                         slot += 8;
  928.                         bits = (bits >> 8) & 255;
  929.                     }
  930.                     int j;
  931.                     for (j = 0; j < 8; j++) {
  932.                         if ((bits & (1 << j)) != 0) {
  933.                             bFound = true;
  934.                             break;
  935.                         }
  936.                     }
  937.                     BCLDebug.Assert(j < 8, "Bad bits?");
  938.                     slot += j;
  939.                     m_ThreadStaticsBits[i] &= ~(1 << slot);
  940.                     break;
  941.                 }
  942.             }
  943.             if (bFound) {
  944.                 slot = slot + 32 * i;
  945.             }
  946.             BCLDebug.Assert(bFound || slot == 0, "Bad bits");
  947.             return slot;
  948.         }
  949. /*=============================================================*/       
  950.        
  951. /*======================================================================
  952.         **  Current thread context is stored in a slot in the thread local store
  953.         **  CurrentContext gets the Context from the slot.
  954.         ======================================================================*/       
  955.        
  956.         public static Context CurrentContext {
  957.             [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  958.             get { return CurrentThread.GetCurrentContextInternal(); }
  959.         }
  960.        
  961.         internal Context GetCurrentContextInternal()
  962.         {
  963.             if (m_Context == null) {
  964.                 m_Context = Context.DefaultContext;
  965.             }
  966.             return m_Context;
  967.         }
  968.        
  969.         [HostProtection(SharedState = true, ExternalThreading = true)]
  970.         internal LogicalCallContext GetLogicalCallContext()
  971.         {
  972.             return ExecutionContext.LogicalCallContext;
  973.         }
  974.        
  975.         [HostProtection(SharedState = true, ExternalThreading = true)]
  976.         internal LogicalCallContext SetLogicalCallContext(LogicalCallContext callCtx)
  977.         {
  978.             LogicalCallContext oldCtx = ExecutionContext.LogicalCallContext;
  979.             ExecutionContext.LogicalCallContext = callCtx;
  980.             return oldCtx;
  981.         }
  982.        
  983.         internal IllogicalCallContext GetIllogicalCallContext()
  984.         {
  985.             return ExecutionContext.IllogicalCallContext;
  986.         }
  987.        
  988.         // Get and set thread's current principal (for role based security).
  989.         public static IPrincipal CurrentPrincipal {
  990.             get {
  991.                 lock (CurrentThread) {
  992.                     IPrincipal principal = (IPrincipal)CallContext.Principal;
  993.                     if (principal == null) {
  994.                         principal = GetDomain().GetThreadPrincipal();
  995.                         CallContext.Principal = principal;
  996.                     }
  997.                     return principal;
  998.                 }
  999.             }
  1000.            
  1001.             [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlPrincipal)]
  1002.             set { CallContext.Principal = value; }
  1003.         }
  1004.        
  1005.         // Private routine called from unmanaged code to set an initial
  1006.         // principal for a newly created thread.
  1007.         private void SetPrincipalInternal(IPrincipal principal)
  1008.         {
  1009.             GetLogicalCallContext().SecurityData.Principal = principal;
  1010.         }
  1011.        
  1012.         // This returns the exposed context for a given context ID.
  1013.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1014.         static internal extern Context GetContextInternal(IntPtr id);
  1015.        
  1016.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1017.         internal extern object InternalCrossContextCallback(Context ctx, IntPtr ctxID, Int32 appDomainID, InternalCrossContextDelegate ftnToCall, object[] args);
  1018.        
  1019.         internal object InternalCrossContextCallback(Context ctx, InternalCrossContextDelegate ftnToCall, object[] args)
  1020.         {
  1021.             return InternalCrossContextCallback(ctx, ctx.InternalContextID, 0, ftnToCall, args);
  1022.         }
  1023.        
  1024.         // CompleteCrossContextCallback is called by the EE after transitioning to the requested context
  1025.         private static object CompleteCrossContextCallback(InternalCrossContextDelegate ftnToCall, object[] args)
  1026.         {
  1027.             return ftnToCall(args);
  1028.         }
  1029.        
  1030. /*======================================================================
  1031.         ** Returns the current domain in which current thread is running.
  1032.         ======================================================================*/       
  1033.        
  1034.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1035.         private static extern AppDomain GetDomainInternal();
  1036.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1037.         private static extern AppDomain GetFastDomainInternal();
  1038.        
  1039.         public static AppDomain GetDomain()
  1040.         {
  1041.             if (CurrentThread.m_Context == null) {
  1042.                 AppDomain ad;
  1043.                 ad = GetFastDomainInternal();
  1044.                 if (ad == null)
  1045.                     ad = GetDomainInternal();
  1046.                 return ad;
  1047.             }
  1048.             else {
  1049.                 BCLDebug.Assert(GetDomainInternal() == CurrentThread.m_Context.AppDomain, "AppDomains on the managed & unmanaged threads should match");
  1050.                 return CurrentThread.m_Context.AppDomain;
  1051.             }
  1052.         }
  1053.        
  1054.        
  1055. /*
  1056.         *  This returns a unique id to identify an appdomain.
  1057.         */       
  1058.         public static int GetDomainID()
  1059.         {
  1060.             return GetDomain().GetId();
  1061.         }
  1062.        
  1063.        
  1064.         // Retrieves the name of the thread.
  1065.         //
  1066.         public string Name {
  1067.                
  1068.             get { return m_Name; }
  1069.             [HostProtection(ExternalThreading = true)]
  1070.             set {
  1071.                 lock (this) {
  1072.                     if (m_Name != null)
  1073.                         throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_WriteOnce"));
  1074.                     m_Name = value;
  1075.                    
  1076.                     InformThreadNameChangeEx(this, m_Name);
  1077.                 }
  1078.             }
  1079.         }
  1080.        
  1081.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1082.         static internal extern void InformThreadNameChangeEx(Thread t, string name);
  1083.        
  1084.         internal object AbortReason {
  1085.             get {
  1086.                 object result = null;
  1087.                 try {
  1088.                     result = GetAbortReason();
  1089.                 }
  1090.                 catch (Exception e) {
  1091.                     throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ExceptionStateCrossAppDomain"), e);
  1092.                 }
  1093.                 return result;
  1094.             }
  1095.             set { SetAbortReason(value); }
  1096.         }
  1097.        
  1098. /*
  1099.         *  This marks the beginning of a critical code region.
  1100.         */       
  1101.         [HostProtection(Synchronization = true, ExternalThreading = true)]
  1102.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1103.         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
  1104.         public static extern void BeginCriticalRegion();
  1105.        
  1106. /*
  1107.         *  This marks the end of a critical code region.
  1108.         */       
  1109.         [HostProtection(Synchronization = true, ExternalThreading = true)]
  1110.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1111.         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
  1112.         public static extern void EndCriticalRegion();
  1113.        
  1114. /*
  1115.         *  This marks the beginning of a code region that requires thread affinity.
  1116.         */       
  1117.         [SecurityPermissionAttribute(SecurityAction.LinkDemand, ControlThread = true)]
  1118.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1119.         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
  1120.         public static extern void BeginThreadAffinity();
  1121.        
  1122. /*
  1123.         *  This marks the end of a code region that requires thread affinity.
  1124.         */       
  1125.         [SecurityPermissionAttribute(SecurityAction.LinkDemand, ControlThread = true)]
  1126.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1127.         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
  1128.         public static extern void EndThreadAffinity();
  1129.        
  1130. /*=========================================================================
  1131.         ** Volatile Read & Write and MemoryBarrier methods.
  1132.         ** Provides the ability to read and write values ensuring that the values
  1133.         ** are read/written each time they are accessed.
  1134.         =========================================================================*/       
  1135.        
  1136.         [MethodImplAttribute(MethodImplOptions.NoInlining)]
  1137.         // disable optimizations
  1138.         public static byte VolatileRead(ref byte address)
  1139.         {
  1140.             byte ret = address;
  1141.             MemoryBarrier();
  1142.             // Call MemoryBarrier to ensure the proper semantic in a portable way.
  1143.             return ret;
  1144.         }
  1145.        
  1146.         [MethodImplAttribute(MethodImplOptions.NoInlining)]
  1147.         // disable optimizations
  1148.         public static short VolatileRead(ref short address)
  1149.         {
  1150.             short ret = address;
  1151.             MemoryBarrier();
  1152.             // Call MemoryBarrier to ensure the proper semantic in a portable way.
  1153.             return ret;
  1154.         }
  1155.        
  1156.         [MethodImplAttribute(MethodImplOptions.NoInlining)]
  1157.         // disable optimizations
  1158.         public static int VolatileRead(ref int address)
  1159.         {
  1160.             int ret = address;
  1161.             MemoryBarrier();
  1162.             // Call MemoryBarrier to ensure the proper semantic in a portable way.
  1163.             return ret;
  1164.         }
  1165.        
  1166.         [MethodImplAttribute(MethodImplOptions.NoInlining)]
  1167.         // disable optimizations
  1168.         public static long VolatileRead(ref long address)
  1169.         {
  1170.             long ret = address;
  1171.             MemoryBarrier();
  1172.             // Call MemoryBarrier to ensure the proper semantic in a portable way.
  1173.             return ret;
  1174.         }
  1175.        
  1176.         [CLSCompliant(false)]
  1177.         [MethodImplAttribute(MethodImplOptions.NoInlining)]
  1178.         // disable optimizations
  1179.         public static sbyte VolatileRead(ref sbyte address)
  1180.         {
  1181.             sbyte ret = address;
  1182.             MemoryBarrier();
  1183.             // Call MemoryBarrier to ensure the proper semantic in a portable way.
  1184.             return ret;
  1185.         }
  1186.        
  1187.         [CLSCompliant(false)]
  1188.         [MethodImplAttribute(MethodImplOptions.NoInlining)]
  1189.         // disable optimizations
  1190.         public static ushort VolatileRead(ref ushort address)
  1191.         {
  1192.             ushort ret = address;
  1193.             MemoryBarrier();
  1194.             // Call MemoryBarrier to ensure the proper semantic in a portable way.
  1195.             return ret;
  1196.         }
  1197.        
  1198.         [CLSCompliant(false)]
  1199.         [MethodImplAttribute(MethodImplOptions.NoInlining)]
  1200.         // disable optimizations
  1201.         public static uint VolatileRead(ref uint address)
  1202.         {
  1203.             uint ret = address;
  1204.             MemoryBarrier();
  1205.             // Call MemoryBarrier to ensure the proper semantic in a portable way.
  1206.             return ret;
  1207.         }
  1208.        
  1209.         [MethodImplAttribute(MethodImplOptions.NoInlining)]
  1210.         // disable optimizations
  1211.         public static IntPtr VolatileRead(ref IntPtr address)
  1212.         {
  1213.             IntPtr ret = address;
  1214.             MemoryBarrier();
  1215.             // Call MemoryBarrier to ensure the proper semantic in a portable way.
  1216.             return ret;
  1217.         }
  1218.        
  1219.         [CLSCompliant(false)]
  1220.         [MethodImplAttribute(MethodImplOptions.NoInlining)]
  1221.         // disable optimizations
  1222.         public static UIntPtr VolatileRead(ref UIntPtr address)
  1223.         {
  1224.             UIntPtr ret = address;
  1225.             MemoryBarrier();
  1226.             // Call MemoryBarrier to ensure the proper semantic in a portable way.
  1227.             return ret;
  1228.         }
  1229.        
  1230.         [CLSCompliant(false)]
  1231.         [MethodImplAttribute(MethodImplOptions.NoInlining)]
  1232.         // disable optimizations
  1233.         public static ulong VolatileRead(ref ulong address)
  1234.         {
  1235.             ulong ret = address;
  1236.             MemoryBarrier();
  1237.             // Call MemoryBarrier to ensure the proper semantic in a portable way.
  1238.             return ret;
  1239.         }
  1240.        
  1241.         [MethodImplAttribute(MethodImplOptions.NoInlining)]
  1242.         // disable optimizations
  1243.         public static float VolatileRead(ref float address)
  1244.         {
  1245.             float ret = address;
  1246.             MemoryBarrier();
  1247.             // Call MemoryBarrier to ensure the proper semantic in a portable way.
  1248.             return ret;
  1249.         }
  1250.        
  1251.         [MethodImplAttribute(MethodImplOptions.NoInlining)]
  1252.         // disable optimizations
  1253.         public static double VolatileRead(ref double address)
  1254.         {
  1255.             double ret = address;
  1256.             MemoryBarrier();
  1257.             // Call MemoryBarrier to ensure the proper semantic in a portable way.
  1258.             return ret;
  1259.         }
  1260.        
  1261.         [MethodImplAttribute(MethodImplOptions.NoInlining)]
  1262.         // disable optimizations
  1263.         public static object VolatileRead(ref object address)
  1264.         {
  1265.             object ret = address;
  1266.             MemoryBarrier();
  1267.             // Call MemoryBarrier to ensure the proper semantic in a portable way.
  1268.             return ret;
  1269.         }
  1270.        
  1271.         [MethodImplAttribute(MethodImplOptions.NoInlining)]
  1272.         // disable optimizations
  1273.         public static void VolatileWrite(ref byte address, byte value)
  1274.         {
  1275.             MemoryBarrier();
  1276.             // Call MemoryBarrier to ensure the proper semantic in a portable way.
  1277.             address = value;
  1278.         }
  1279.        
  1280.         [MethodImplAttribute(MethodImplOptions.NoInlining)]
  1281.         // disable optimizations
  1282.         public static void VolatileWrite(ref short address, short value)
  1283.         {
  1284.             MemoryBarrier();
  1285.             // Call MemoryBarrier to ensure the proper semantic in a portable way.
  1286.             address = value;
  1287.         }
  1288.        
  1289.         [MethodImplAttribute(MethodImplOptions.NoInlining)]
  1290.         // disable optimizations
  1291.         public static void VolatileWrite(ref int address, int value)
  1292.         {
  1293.             MemoryBarrier();
  1294.             // Call MemoryBarrier to ensure the proper semantic in a portable way.
  1295.             address = value;
  1296.         }
  1297.        
  1298.         [MethodImplAttribute(MethodImplOptions.NoInlining)]
  1299.         // disable optimizations
  1300.         public static void VolatileWrite(ref long address, long value)
  1301.         {
  1302.             MemoryBarrier();
  1303.             // Call MemoryBarrier to ensure the proper semantic in a portable way.
  1304.             address = value;
  1305.         }
  1306.        
  1307.         [CLSCompliant(false)]
  1308.         [MethodImplAttribute(MethodImplOptions.NoInlining)]
  1309.         // disable optimizations
  1310.         public static void VolatileWrite(ref sbyte address, sbyte value)
  1311.         {
  1312.             MemoryBarrier();
  1313.             // Call MemoryBarrier to ensure the proper semantic in a portable way.
  1314.             address = value;
  1315.         }
  1316.        
  1317.         [CLSCompliant(false)]
  1318.         [MethodImplAttribute(MethodImplOptions.NoInlining)]
  1319.         // disable optimizations
  1320.         public static void VolatileWrite(ref ushort address, ushort value)
  1321.         {
  1322.             MemoryBarrier();
  1323.             // Call MemoryBarrier to ensure the proper semantic in a portable way.
  1324.             address = value;
  1325.         }
  1326.        
  1327.         [CLSCompliant(false)]
  1328.         [MethodImplAttribute(MethodImplOptions.NoInlining)]
  1329.         // disable optimizations
  1330.         public static void VolatileWrite(ref uint address, uint value)
  1331.         {
  1332.             MemoryBarrier();
  1333.             // Call MemoryBarrier to ensure the proper semantic in a portable way.
  1334.             address = value;
  1335.         }
  1336.        
  1337.         [MethodImplAttribute(MethodImplOptions.NoInlining)]
  1338.         // disable optimizations
  1339.         public static void VolatileWrite(ref IntPtr address, IntPtr value)
  1340.         {
  1341.             MemoryBarrier();
  1342.             // Call MemoryBarrier to ensure the proper semantic in a portable way.
  1343.             address = value;
  1344.         }
  1345.        
  1346.         [CLSCompliant(false)]
  1347.         [MethodImplAttribute(MethodImplOptions.NoInlining)]
  1348.         // disable optimizations
  1349.         public static void VolatileWrite(ref UIntPtr address, UIntPtr value)
  1350.         {
  1351.             MemoryBarrier();
  1352.             // Call MemoryBarrier to ensure the proper semantic in a portable way.
  1353.             address = value;
  1354.         }
  1355.        
  1356.         [CLSCompliant(false)]
  1357.         [MethodImplAttribute(MethodImplOptions.NoInlining)]
  1358.         // disable optimizations
  1359.         public static void VolatileWrite(ref ulong address, ulong value)
  1360.         {
  1361.             MemoryBarrier();
  1362.             // Call MemoryBarrier to ensure the proper semantic in a portable way.
  1363.             address = value;
  1364.         }
  1365.        
  1366.         [MethodImplAttribute(MethodImplOptions.NoInlining)]
  1367.         // disable optimizations
  1368.         public static void VolatileWrite(ref float address, float value)
  1369.         {
  1370.             MemoryBarrier();
  1371.             // Call MemoryBarrier to ensure the proper semantic in a portable way.
  1372.             address = value;
  1373.         }
  1374.        
  1375.         [MethodImplAttribute(MethodImplOptions.NoInlining)]
  1376.         // disable optimizations
  1377.         public static void VolatileWrite(ref double address, double value)
  1378.         {
  1379.             MemoryBarrier();
  1380.             // Call MemoryBarrier to ensure the proper semantic in a portable way.
  1381.             address = value;
  1382.         }
  1383.        
  1384.         [MethodImplAttribute(MethodImplOptions.NoInlining)]
  1385.         // disable optimizations
  1386.         public static void VolatileWrite(ref object address, object value)
  1387.         {
  1388.             MemoryBarrier();
  1389.             // Call MemoryBarrier to ensure the proper semantic in a portable way.
  1390.             address = value;
  1391.         }
  1392.        
  1393.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1394.         public static extern void MemoryBarrier();
  1395.        
  1396.         //We need to mark thread statics array for AppDomain leak checking purpose
  1397.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1398.         private static extern void SetIsThreadStaticsArray(object o);
  1399.        
  1400.         private static LocalDataStoreMgr LocalDataStoreManager {
  1401.             get {
  1402.                 if (s_LocalDataStoreMgr == null) {
  1403.                     lock (s_SyncObject) {
  1404.                         if (s_LocalDataStoreMgr == null)
  1405.                             s_LocalDataStoreMgr = new LocalDataStoreMgr();
  1406.                     }
  1407.                 }
  1408.                
  1409.                 return s_LocalDataStoreMgr;
  1410.             }
  1411.         }
  1412.        
  1413.         void _Thread.GetTypeInfoCount(out uint pcTInfo)
  1414.         {
  1415.             throw new NotImplementedException();
  1416.         }
  1417.        
  1418.         void _Thread.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
  1419.         {
  1420.             throw new NotImplementedException();
  1421.         }
  1422.        
  1423.         void _Thread.GetIDsOfNames(        [In()]
  1424. ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
  1425.         {
  1426.             throw new NotImplementedException();
  1427.         }
  1428.        
  1429.         void _Thread.Invoke(uint dispIdMember,         [In()]
  1430. ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
  1431.         {
  1432.             throw new NotImplementedException();
  1433.         }
  1434.        
  1435.         // Helper function to set the AbortReason for a thread abort.
  1436.         // Checks that they're not alredy set, and then atomically updates
  1437.         // the reason info (object + ADID).
  1438.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1439.         internal extern void SetAbortReason(object o);
  1440.        
  1441.         // Helper function to retrieve the AbortReason from a thread
  1442.         // abort. Will perform cross-AppDomain marshalling if the object
  1443.         // lives in a different AppDomain from the requester.
  1444.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1445.         internal extern object GetAbortReason();
  1446.        
  1447.         // Helper function to clear the AbortReason. Takes care of
  1448.         // AppDomain related cleanup if required.
  1449.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1450.         internal extern void ClearAbortReason();
  1451.        
  1452.     }
  1453.     // End of class Thread
  1454.     // declaring a local var of this enum type and passing it by ref into a function that needs to do a
  1455.     // stack crawl will both prevent inlining of the calle and pass an ESP point to stack crawl to
  1456.     // Declaring these in EH clauses is illegal; they must declared in the main method body
  1457.     [Serializable()]
  1458.     internal enum StackCrawlMark
  1459.     {
  1460.         LookForMe = 0,
  1461.         LookForMyCaller = 1,
  1462.         LookForMyCallersCaller = 2,
  1463.         LookForThread = 3
  1464.     }
  1465.    
  1466. }

Developer Fusion