70559108ed30b97f85a93ae0bf61c01a2b5e9b93
[mono.git] / mcs / class / referencesource / mscorlib / system / threading / thread.cs
1 // ==++==
2 //
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 //
5 // ==--==
6 //
7 // <OWNER>Microsoft</OWNER>
8 /*=============================================================================
9 **
10 ** Class: Thread
11 **
12 **
13 ** Purpose: Class for creating and managing a thread.
14 **
15 **
16 =============================================================================*/
17
18 namespace System.Threading {
19     using System.Threading;
20     using System.Runtime;
21     using System.Runtime.InteropServices;
22 #if FEATURE_REMOTING    
23     using System.Runtime.Remoting.Contexts;
24     using System.Runtime.Remoting.Messaging;
25 #endif
26     using System;
27     using System.Diagnostics;
28     using System.Security.Permissions;
29     using System.Security.Principal;
30     using System.Globalization;
31     using System.Collections.Generic;
32     using System.Runtime.Serialization;
33     using System.Runtime.CompilerServices;
34     using System.Runtime.ConstrainedExecution;
35     using System.Security;
36     using System.Runtime.Versioning;
37     using System.Diagnostics.Contracts;
38
39     internal delegate Object InternalCrossContextDelegate(Object[] args);
40
41     internal class ThreadHelper
42     {
43         [System.Security.SecuritySafeCritical]
44         static 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
59         [System.Security.SecurityCritical]
60         static internal ContextCallback _ccb = new ContextCallback(ThreadStart_Context);
61         
62         [System.Security.SecurityCritical]
63         static private void ThreadStart_Context(Object state)
64         {
65             ThreadHelper t = (ThreadHelper)state;
66             if (t._start is ThreadStart)
67             {
68                 ((ThreadStart)t._start)();
69             }
70             else
71             {
72                 ((ParameterizedThreadStart)t._start)(t._startArg);
73             }
74         }
75
76         // call back helper
77         #if FEATURE_CORECLR
78         [System.Security.SecuritySafeCritical] // auto-generated
79         #else
80         [System.Security.SecurityCritical]
81         #endif
82         internal void ThreadStart(object obj)
83         {               
84             _startArg = obj;
85             if (_executionContext != null) 
86             {
87                 ExecutionContext.Run(_executionContext, _ccb, (Object)this);
88             }
89             else
90             {
91                 ((ParameterizedThreadStart)_start)(obj);
92             }
93         }
94
95         // call back helper
96         #if FEATURE_CORECLR
97         [System.Security.SecuritySafeCritical] // auto-generated
98         #else
99         [System.Security.SecurityCritical]
100         #endif
101         internal void ThreadStart()
102         {
103             if (_executionContext != null) 
104             {
105                 ExecutionContext.Run(_executionContext, _ccb, (Object)this);
106             }
107             else
108             {
109                 ((ThreadStart)_start)();
110             }
111         }
112     }
113 #if !MONO
114     internal struct ThreadHandle
115     {
116         private IntPtr m_ptr;
117
118         internal ThreadHandle(IntPtr pThread)
119         {
120             m_ptr = pThread;
121         }
122     }
123 #endif
124     // deliberately not [serializable]
125     [ClassInterface(ClassInterfaceType.None)]
126     [ComDefaultInterface(typeof(_Thread))]
127 [System.Runtime.InteropServices.ComVisible(true)]
128     public sealed partial class Thread : CriticalFinalizerObject
129 #if !MOBILE
130     , _Thread
131 #endif
132     {
133 #if !MONO
134         /*=========================================================================
135         ** Data accessed from managed code that needs to be defined in
136         ** ThreadBaseObject to maintain alignment between the two classes.
137         ** DON'T CHANGE THESE UNLESS YOU MODIFY ThreadBaseObject in vm\object.h
138         =========================================================================*/
139 #if FEATURE_REMOTING        
140         private Context         m_Context;
141 #endif 
142 #if !FEATURE_CORECLR
143         private ExecutionContext m_ExecutionContext;    // this call context follows the logical thread
144 #endif
145
146         private String          m_Name;
147         private Delegate        m_Delegate;             // Delegate
148         
149 #if FEATURE_LEAK_CULTURE_INFO 
150         private CultureInfo     m_CurrentCulture;
151         private CultureInfo     m_CurrentUICulture;
152 #endif
153         private Object          m_ThreadStartArg;
154
155         /*=========================================================================
156         ** The base implementation of Thread is all native.  The following fields
157         ** should never be used in the C# code.  They are here to define the proper
158         ** space so the thread object may be allocated.  DON'T CHANGE THESE UNLESS
159         ** YOU MODIFY ThreadBaseObject in vm\object.h
160         =========================================================================*/
161 #pragma warning disable 169
162 #pragma warning disable 414  // These fields are not used from managed.
163         // IntPtrs need to be together, and before ints, because IntPtrs are 64-bit
164         //  fields on 64-bit platforms, where they will be sorted together.
165                                                         
166         private IntPtr  DONT_USE_InternalThread;        // Pointer
167         private int     m_Priority;                     // INT32
168         private int     m_ManagedThreadId;              // INT32
169
170 #pragma warning restore 414
171 #pragma warning restore 169
172
173         private bool m_ExecutionContextBelongsToOuterScope;
174 #if DEBUG
175         private bool m_ForbidExecutionContextMutation;
176 #endif
177 #endif
178         /*=========================================================================
179         ** This manager is responsible for storing the global data that is
180         ** shared amongst all the thread local stores.
181         =========================================================================*/
182         static private LocalDataStoreMgr s_LocalDataStoreMgr;
183
184         /*=========================================================================
185         ** Thread-local data store
186         =========================================================================*/
187         [ThreadStatic]
188         static private LocalDataStoreHolder s_LocalDataStore;
189
190         // Do not move! Order of above fields needs to be preserved for alignment
191         // with native code
192         // See code:#threadCultureInfo
193 #if !FEATURE_LEAK_CULTURE_INFO
194         [ThreadStatic]
195         internal static CultureInfo     m_CurrentCulture;
196         [ThreadStatic]
197         internal static CultureInfo     m_CurrentUICulture;
198 #endif
199
200         static AsyncLocal<CultureInfo> s_asyncLocalCurrentCulture; 
201         static AsyncLocal<CultureInfo> s_asyncLocalCurrentUICulture;
202
203         static void AsyncLocalSetCurrentCulture(AsyncLocalValueChangedArgs<CultureInfo> args)
204         {
205 #if FEATURE_LEAK_CULTURE_INFO 
206             Thread.CurrentThread.m_CurrentCulture = args.CurrentValue;
207 #else
208             m_CurrentCulture = args.CurrentValue;
209 #endif // FEATURE_LEAK_CULTURE_INFO
210         }
211
212         static void AsyncLocalSetCurrentUICulture(AsyncLocalValueChangedArgs<CultureInfo> args)
213         {
214 #if FEATURE_LEAK_CULTURE_INFO 
215             Thread.CurrentThread.m_CurrentUICulture = args.CurrentValue;
216 #else
217             m_CurrentUICulture = args.CurrentValue;
218 #endif // FEATURE_LEAK_CULTURE_INFO
219         }
220
221 #if FEATURE_CORECLR
222         // Adding an empty default ctor for annotation purposes
223         [System.Security.SecuritySafeCritical] // auto-generated
224         internal Thread(){}
225 #endif // FEATURE_CORECLR
226
227         /*=========================================================================
228         ** Creates a new Thread object which will begin execution at
229         ** start.ThreadStart on a new thread when the Start method is called.
230         **
231         ** Exceptions: ArgumentNullException if start == null.
232         =========================================================================*/
233         [System.Security.SecuritySafeCritical]  // auto-generated
234         public Thread(ThreadStart start) {
235             if (start == null) {
236                 throw new ArgumentNullException("start");
237             }
238             Contract.EndContractBlock();
239             SetStartHelper((Delegate)start,0);  //0 will setup Thread with default stackSize
240         }
241
242         [System.Security.SecuritySafeCritical]  // auto-generated
243         public Thread(ThreadStart start, int maxStackSize) {
244             if (start == null) {
245                 throw new ArgumentNullException("start");
246             }
247             if (0 > maxStackSize)
248                 throw new ArgumentOutOfRangeException("maxStackSize",Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
249             Contract.EndContractBlock();
250             SetStartHelper((Delegate)start, maxStackSize);
251         }
252
253         [System.Security.SecuritySafeCritical]  // auto-generated
254         public Thread(ParameterizedThreadStart start) {
255             if (start == null) {
256                 throw new ArgumentNullException("start");
257             }
258             Contract.EndContractBlock();
259             SetStartHelper((Delegate)start, 0);
260         }
261
262         [System.Security.SecuritySafeCritical]  // auto-generated
263         public Thread(ParameterizedThreadStart start, int maxStackSize) {
264             if (start == null) {
265                 throw new ArgumentNullException("start");
266             }
267             if (0 > maxStackSize)
268                 throw new ArgumentOutOfRangeException("maxStackSize",Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
269             Contract.EndContractBlock();
270             SetStartHelper((Delegate)start, maxStackSize);
271         }
272 #if !MONO
273         [ComVisible(false)]
274         public override int GetHashCode()
275         {
276             return m_ManagedThreadId;
277         }
278
279         extern public int ManagedThreadId
280         {
281             [ResourceExposure(ResourceScope.None)]
282             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
283             [MethodImplAttribute(MethodImplOptions.InternalCall)]
284             [System.Security.SecuritySafeCritical]  // auto-generated
285             get;
286         }
287
288         // Returns handle for interop with EE. The handle is guaranteed to be non-null.
289         internal unsafe ThreadHandle GetNativeHandle()
290         {
291             IntPtr thread = DONT_USE_InternalThread;
292
293             // This should never happen under normal circumstances. m_assembly is always assigned before it is handed out to the user.
294             // There are ways how to create an unitialized objects through remoting, etc. Avoid AVing in the EE by throwing a nice
295             // exception here.
296             if (thread.IsNull())
297                 throw new ArgumentException(null, Environment.GetResourceString("Argument_InvalidHandle"));
298
299             return new ThreadHandle(thread);
300         }
301 #endif
302
303         /*=========================================================================
304         ** Spawns off a new thread which will begin executing at the ThreadStart
305         ** method on the IThreadable interface passed in the constructor. Once the
306         ** thread is dead, it cannot be restarted with another call to Start.
307         **
308         ** Exceptions: ThreadStateException if the thread has already been started.
309         =========================================================================*/
310         [HostProtection(Synchronization=true,ExternalThreading=true)]
311         [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
312         public void Start()
313         {
314             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
315             Start(ref stackMark);
316         }
317
318         [HostProtection(Synchronization=true,ExternalThreading=true)]
319         [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
320         public void Start(object parameter)
321         {
322             //In the case of a null delegate (second call to start on same thread)
323             //    StartInternal method will take care of the error reporting
324             if(m_Delegate is ThreadStart)
325             {
326                 //We expect the thread to be setup with a ParameterizedThreadStart
327                 //    if this constructor is called.
328                 //If we got here then that wasn't the case
329                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ThreadWrongThreadStart"));
330             }
331             m_ThreadStartArg = parameter;
332             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
333             Start(ref stackMark);
334         }
335
336         [System.Security.SecuritySafeCritical]
337         private void Start(ref StackCrawlMark stackMark)
338         {
339 #if FEATURE_COMINTEROP_APARTMENT_SUPPORT
340             // Eagerly initialize the COM Apartment state of the thread if we're allowed to.
341             StartupSetApartmentStateInternal();
342 #endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT
343
344             // Attach current thread's security principal object to the new
345             // thread. Be careful not to bind the current thread to a principal
346             // if it's not already bound.
347             if (m_Delegate != null)
348             {
349                 // If we reach here with a null delegate, something is broken. But we'll let the StartInternal method take care of
350                 // reporting an error. Just make sure we dont try to dereference a null delegate.
351                 ThreadHelper t = (ThreadHelper)(m_Delegate.Target);
352                 ExecutionContext ec = ExecutionContext.Capture(
353                     ref stackMark,
354                     ExecutionContext.CaptureOptions.IgnoreSyncCtx);
355                 t.SetExecutionContextHelper(ec);
356             }
357 #if FEATURE_IMPERSONATION
358             IPrincipal principal = (IPrincipal)CallContext.Principal;
359 #else
360             IPrincipal principal = null;
361 #endif
362             StartInternal(principal, ref stackMark);
363         }
364
365
366 #if !FEATURE_CORECLR
367         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
368         internal ExecutionContext.Reader GetExecutionContextReader()
369         {
370             return new ExecutionContext.Reader(m_ExecutionContext);
371         }
372
373         internal bool ExecutionContextBelongsToCurrentScope
374         {
375             get { return !m_ExecutionContextBelongsToOuterScope; }
376             set { m_ExecutionContextBelongsToOuterScope = !value; }
377         }
378
379 #if !MONO && DEBUG
380         internal bool ForbidExecutionContextMutation
381         {
382             set { m_ForbidExecutionContextMutation = value; }
383         }
384 #endif
385
386         // note: please don't access this directly from mscorlib.  Use GetMutableExecutionContext or GetExecutionContextReader instead.
387         public  ExecutionContext ExecutionContext
388         {
389             [SecuritySafeCritical]
390             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
391             get
392             {
393                 ExecutionContext result;
394                 if (this == Thread.CurrentThread)
395                     result = GetMutableExecutionContext();
396                 else
397                     result = m_ExecutionContext;
398
399                 return result;
400             }
401         }
402
403         [SecurityCritical]
404         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
405         internal ExecutionContext GetMutableExecutionContext()
406         {
407             Contract.Assert(Thread.CurrentThread == this);
408 #if !MONO && DEBUG
409             Contract.Assert(!m_ForbidExecutionContextMutation);
410 #endif
411             if (m_ExecutionContext == null)
412             {
413                 m_ExecutionContext = new ExecutionContext();
414             }
415             else if (!ExecutionContextBelongsToCurrentScope)
416             {
417                 ExecutionContext copy = m_ExecutionContext.CreateMutableCopy();
418                 m_ExecutionContext = copy;
419             }
420
421             ExecutionContextBelongsToCurrentScope = true;
422             return m_ExecutionContext;
423         }
424
425         [SecurityCritical]
426         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
427         internal void SetExecutionContext(ExecutionContext value, bool belongsToCurrentScope) 
428         {
429             m_ExecutionContext = value;
430             ExecutionContextBelongsToCurrentScope = belongsToCurrentScope;
431         }
432
433         [SecurityCritical]
434         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
435         internal void SetExecutionContext(ExecutionContext.Reader value, bool belongsToCurrentScope)
436         {
437             m_ExecutionContext = value.DangerousGetRawExecutionContext();
438             ExecutionContextBelongsToCurrentScope = belongsToCurrentScope;
439         }
440 #endif //!FEATURE_CORECLR
441
442 #if !MONO
443         [System.Security.SecurityCritical]  // auto-generated
444         [ResourceExposure(ResourceScope.None)]
445         [MethodImplAttribute(MethodImplOptions.InternalCall)]
446         private extern void StartInternal(IPrincipal principal, ref StackCrawlMark stackMark);
447 #endif
448 #if FEATURE_COMPRESSEDSTACK || MONO
449         /// <internalonly/>
450         [System.Security.SecurityCritical]  // auto-generated_required
451         [DynamicSecurityMethodAttribute()]
452         [Obsolete("Thread.SetCompressedStack is no longer supported. Please use the System.Threading.CompressedStack class")]         
453         public void SetCompressedStack( CompressedStack stack )
454         {
455             throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ThreadAPIsNotSupported"));
456         }
457 #if !MONO
458         [System.Security.SecurityCritical]  // auto-generated
459         [ResourceExposure(ResourceScope.None)]
460         [MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
461         internal extern IntPtr SetAppDomainStack( SafeCompressedStackHandle csHandle);
462
463         [System.Security.SecurityCritical]  // auto-generated
464         [ResourceExposure(ResourceScope.None)]
465         [MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
466         internal extern void RestoreAppDomainStack( IntPtr appDomainStack);
467 #endif
468
469         /// <internalonly/>
470         [System.Security.SecurityCritical]  // auto-generated_required
471         [Obsolete("Thread.GetCompressedStack is no longer supported. Please use the System.Threading.CompressedStack class")]
472         public CompressedStack GetCompressedStack()
473         {
474             throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ThreadAPIsNotSupported"));
475         }
476 #endif // #if FEATURE_COMPRESSEDSTACK
477 #if !MONO
478
479         // Helper method to get a logical thread ID for StringBuilder (for
480         // correctness) and for FileStream's async code path (for perf, to
481         // avoid creating a Thread instance).
482         [System.Security.SecurityCritical]  // auto-generated
483         [ResourceExposure(ResourceScope.None)]
484         [MethodImplAttribute(MethodImplOptions.InternalCall)]
485         internal extern static IntPtr InternalGetCurrentThread();
486
487         /*=========================================================================
488         ** Raises a ThreadAbortException in the thread, which usually
489         ** results in the thread's death. The ThreadAbortException is a special
490         ** exception that is not catchable. The finally clauses of all try
491         ** statements will be executed before the thread dies. This includes the
492         ** finally that a thread might be executing at the moment the Abort is raised.
493         ** The thread is not stopped immediately--you must Join on the
494         ** thread to guarantee it has stopped.
495         ** It is possible for a thread to do an unbounded amount of computation in
496         ** the finally's and thus indefinitely delay the threads death.
497         ** If Abort() is called on a thread that has not been started, the thread
498         ** will abort when Start() is called.
499         ** If Abort is called twice on the same thread, a DuplicateThreadAbort
500         ** exception is thrown.
501         =========================================================================*/
502
503 #if !FEATURE_CORECLR
504         [System.Security.SecuritySafeCritical]  // auto-generated
505         [SecurityPermissionAttribute(SecurityAction.Demand, ControlThread=true)]
506         public void Abort(Object stateInfo)
507         {
508             // If two aborts come at the same time, it is possible that the state info
509             //  gets set by one, and the actual abort gets delivered by another. But this
510             //  is not distinguishable by an application.
511             // The accessor helper will only set the value if it isn't already set,
512             //  and that particular bit of native code can test much faster than this
513             //  code could, because testing might cause a cross-appdomain marshalling.
514             AbortReason = stateInfo;
515
516             // Note: we demand ControlThread permission, then call AbortInternal directly
517             // rather than delegating to the Abort() function below. We do this to ensure
518             // that only callers with ControlThread are allowed to change the AbortReason
519             // of the thread. We call AbortInternal directly to avoid demanding the same
520             // permission twice.
521             AbortInternal();
522         }
523 #endif
524
525         #if FEATURE_CORECLR
526         [System.Security.SecurityCritical] // auto-generated
527         #else
528         [System.Security.SecuritySafeCritical]
529         #endif
530 #pragma warning disable 618
531         [SecurityPermissionAttribute(SecurityAction.Demand, ControlThread = true)]
532 #pragma warning restore 618
533         public void Abort()
534         {
535 #if FEATURE_LEGACYNETCF
536             if(CompatibilitySwitches.IsAppEarlierThanWindowsPhone8)
537             {
538                 System.Reflection.Assembly callingAssembly = System.Reflection.Assembly.GetCallingAssembly();
539                 if(callingAssembly != null && !callingAssembly.IsProfileAssembly)
540                 {
541                     string caller = new StackFrame(1).GetMethod().FullName;
542                     string callee = System.Reflection.MethodBase.GetCurrentMethod().FullName;
543                     throw new MethodAccessException(String.Format(
544                         CultureInfo.CurrentCulture,
545                         Environment.GetResourceString("Arg_MethodAccessException_WithCaller"),
546                         caller,
547                         callee));
548                 }
549             }
550 #endif // FEATURE_LEGACYNETCF
551             AbortInternal();
552         }
553
554         // Internal helper (since we can't place security demands on
555         // ecalls/fcalls).
556         [System.Security.SecurityCritical]  // auto-generated
557         [ResourceExposure(ResourceScope.None)]
558         [MethodImplAttribute(MethodImplOptions.InternalCall)]
559         private extern void AbortInternal();
560 #endif
561 #if !FEATURE_CORECLR || MONO
562         /*=========================================================================
563         ** Resets a thread abort.
564         ** Should be called by trusted code only
565           =========================================================================*/
566         [System.Security.SecuritySafeCritical]  // auto-generated
567         [SecurityPermissionAttribute(SecurityAction.Demand, ControlThread=true)]
568         public static void ResetAbort()
569         {
570             Thread thread = Thread.CurrentThread;
571             if ((thread.ThreadState & ThreadState.AbortRequested) == 0)
572                 throw new ThreadStateException(Environment.GetResourceString("ThreadState_NoAbortRequested"));
573             thread.ResetAbortNative();
574             thread.ClearAbortReason();
575         }
576
577         [System.Security.SecurityCritical]  // auto-generated
578         [ResourceExposure(ResourceScope.None)]
579         [MethodImplAttribute(MethodImplOptions.InternalCall)]
580         private extern void ResetAbortNative();
581
582         /*=========================================================================
583         ** Suspends the thread. If the thread is already suspended, this call has
584         ** no effect.
585         **
586         ** Exceptions: ThreadStateException if the thread has not been started or
587         **             it is dead.
588         =========================================================================*/
589         [System.Security.SecuritySafeCritical]  // auto-generated
590         [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)]
591         [SecurityPermission(SecurityAction.Demand, ControlThread=true)]
592         public void Suspend() { SuspendInternal(); }
593
594         // Internal helper (since we can't place security demands on
595         // ecalls/fcalls).
596         [System.Security.SecurityCritical]  // auto-generated
597         [ResourceExposure(ResourceScope.None)]
598         [MethodImplAttribute(MethodImplOptions.InternalCall)]
599         private extern void SuspendInternal();
600
601         /*=========================================================================
602         ** Resumes a thread that has been suspended.
603         **
604         ** Exceptions: ThreadStateException if the thread has not been started or
605         **             it is dead or it isn't in the suspended state.
606         =========================================================================*/
607         [System.Security.SecuritySafeCritical]  // auto-generated
608         [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)]
609         [SecurityPermission(SecurityAction.Demand, ControlThread=true)]
610         public void Resume() { ResumeInternal(); }
611
612         // Internal helper (since we can't place security demands on
613         // ecalls/fcalls).
614         [System.Security.SecurityCritical]  // auto-generated
615         [ResourceExposure(ResourceScope.None)]
616         [MethodImplAttribute(MethodImplOptions.InternalCall)]
617         private extern void ResumeInternal();
618
619         /*=========================================================================
620         ** Interrupts a thread that is inside a Wait(), Sleep() or Join().  If that
621         ** thread is not currently blocked in that manner, it will be interrupted
622         ** when it next begins to block.
623         =========================================================================*/
624         [System.Security.SecuritySafeCritical]  // auto-generated
625         [SecurityPermission(SecurityAction.Demand, ControlThread=true)]
626         public void Interrupt() { InterruptInternal(); }
627
628         // Internal helper (since we can't place security demands on
629         // ecalls/fcalls).
630         [System.Security.SecurityCritical]  // auto-generated
631         [ResourceExposure(ResourceScope.None)]
632         [MethodImplAttribute(MethodImplOptions.InternalCall)]
633         private extern void InterruptInternal();
634 #endif
635
636         /*=========================================================================
637         ** Returns the priority of the thread.
638         **
639         ** Exceptions: ThreadStateException if the thread is dead.
640         =========================================================================*/
641
642         public ThreadPriority Priority {
643             [System.Security.SecuritySafeCritical]  // auto-generated
644             get { return (ThreadPriority)GetPriorityNative(); }
645             [System.Security.SecuritySafeCritical]  // auto-generated
646             [HostProtection(SelfAffectingThreading=true)]
647             set { SetPriorityNative((int)value); }
648         }
649         [System.Security.SecurityCritical]  // auto-generated
650         [ResourceExposure(ResourceScope.None)]
651         [MethodImplAttribute(MethodImplOptions.InternalCall)]
652         private extern int GetPriorityNative();
653         [System.Security.SecurityCritical]  // auto-generated
654         [ResourceExposure(ResourceScope.None)]
655         [MethodImplAttribute(MethodImplOptions.InternalCall)]
656         private extern void SetPriorityNative(int priority);
657 #if !MONO
658         /*=========================================================================
659         ** Returns true if the thread has been started and is not dead.
660         =========================================================================*/
661         public extern bool IsAlive {
662             [System.Security.SecuritySafeCritical]  // auto-generated
663             [MethodImpl(MethodImplOptions.InternalCall)]
664             get;
665         }
666
667         /*=========================================================================
668         ** Returns true if the thread is a threadpool thread.
669         =========================================================================*/
670         public extern bool IsThreadPoolThread {
671             [System.Security.SecuritySafeCritical]  // auto-generated
672             [MethodImpl(MethodImplOptions.InternalCall)]
673             get;
674         }
675 #endif
676         /*=========================================================================
677         ** Waits for the thread to die or for timeout milliseconds to elapse.
678         ** Returns true if the thread died, or false if the wait timed out. If
679         ** Timeout.Infinite is given as the parameter, no timeout will occur.
680         **
681         ** Exceptions: ArgumentException if timeout < 0.
682         **             ThreadInterruptedException if the thread is interrupted while waiting.
683         **             ThreadStateException if the thread has not been started yet.
684         =========================================================================*/
685         [System.Security.SecurityCritical]
686         [ResourceExposure(ResourceScope.None)]
687         [MethodImplAttribute(MethodImplOptions.InternalCall)]
688         private extern bool JoinInternal(int millisecondsTimeout);
689
690         [System.Security.SecuritySafeCritical]
691         [HostProtection(Synchronization=true, ExternalThreading=true)]
692         public void Join()
693         {
694             JoinInternal(Timeout.Infinite);
695         }
696
697         [System.Security.SecuritySafeCritical]
698         [HostProtection(Synchronization=true, ExternalThreading=true)]
699         public bool Join(int millisecondsTimeout)
700         {
701 #if MONO
702             if (millisecondsTimeout < Timeout.Infinite)
703                 throw new ArgumentOutOfRangeException("millisecondsTimeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
704 #endif
705             return JoinInternal(millisecondsTimeout);
706         }
707
708         [HostProtection(Synchronization=true, ExternalThreading=true)]
709         public bool Join(TimeSpan timeout)
710         {
711             long tm = (long)timeout.TotalMilliseconds;
712             if (tm < -1 || tm > (long) Int32.MaxValue)
713                 throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
714
715             return Join((int)tm);
716         }
717
718         /*=========================================================================
719         ** Suspends the current thread for timeout milliseconds. If timeout == 0,
720         ** forces the thread to give up the remainer of its timeslice.  If timeout
721         ** == Timeout.Infinite, no timeout will occur.
722         **
723         ** Exceptions: ArgumentException if timeout < 0.
724         **             ThreadInterruptedException if the thread is interrupted while sleeping.
725         =========================================================================*/
726         [System.Security.SecurityCritical]  // auto-generated
727         [ResourceExposure(ResourceScope.None)]
728         [MethodImplAttribute(MethodImplOptions.InternalCall)]
729         private static extern void SleepInternal(int millisecondsTimeout);
730
731         [System.Security.SecuritySafeCritical]  // auto-generated
732         public static void Sleep(int millisecondsTimeout)
733         {
734 #if MONO
735             if (millisecondsTimeout < Timeout.Infinite)
736                 throw new ArgumentOutOfRangeException("millisecondsTimeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
737 #endif
738             SleepInternal(millisecondsTimeout);
739 #if !MONO
740             // Ensure we don't return to app code when the pause is underway
741             if(AppDomainPauseManager.IsPaused)
742                 AppDomainPauseManager.ResumeEvent.WaitOneWithoutFAS();
743 #endif
744         }
745
746         public static void Sleep(TimeSpan timeout)
747         {
748             long tm = (long)timeout.TotalMilliseconds;
749             if (tm < -1 || tm > (long) Int32.MaxValue)
750                 throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
751             Sleep((int)tm);
752         }
753
754 #if !MONO
755         /* wait for a length of time proportial to 'iterations'.  Each iteration is should
756            only take a few machine instructions.  Calling this API is preferable to coding
757            a explict busy loop because the hardware can be informed that it is busy waiting. */
758
759         [System.Security.SecurityCritical]  // auto-generated
760         [MethodImplAttribute(MethodImplOptions.InternalCall),
761          HostProtection(Synchronization=true,ExternalThreading=true),
762          ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success),
763          ResourceExposure(ResourceScope.None)]
764         private static extern void SpinWaitInternal(int iterations);
765
766         [System.Security.SecuritySafeCritical]  // auto-generated
767         [HostProtection(Synchronization=true,ExternalThreading=true),
768          ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
769         public static void SpinWait(int iterations)
770         {
771             SpinWaitInternal(iterations);
772         }
773 #endif
774         [System.Security.SecurityCritical]  // auto-generated
775         [ResourceExposure(ResourceScope.None)]
776         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
777         [SuppressUnmanagedCodeSecurity]
778         [HostProtection(Synchronization = true, ExternalThreading = true),
779          ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
780         private static extern bool YieldInternal();
781
782         [System.Security.SecuritySafeCritical]  // auto-generated
783         [HostProtection(Synchronization = true, ExternalThreading = true),
784          ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
785         public static bool Yield()
786         {
787             return YieldInternal();
788         }
789
790 #if !MONO
791         public static Thread CurrentThread {
792             [System.Security.SecuritySafeCritical]  // auto-generated
793             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
794             get {
795                 Contract.Ensures(Contract.Result<Thread>() != null);
796                 return GetCurrentThreadNative();
797             }
798         }
799         [System.Security.SecurityCritical]  // auto-generated
800         [ResourceExposure(ResourceScope.None)]
801         [MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
802         private static extern Thread GetCurrentThreadNative();
803 #endif
804         [System.Security.SecurityCritical]  // auto-generated
805         private void SetStartHelper(Delegate start, int maxStackSize)
806         {
807 #if MONO
808             maxStackSize = GetProcessDefaultStackSize(maxStackSize);
809 #else
810 #if FEATURE_CORECLR
811             // We only support default stacks in CoreCLR
812             Contract.Assert(maxStackSize == 0);
813 #else
814             // Only fully-trusted code is allowed to create "large" stacks.  Partial-trust falls back to
815             // the default stack size.
816             ulong defaultStackSize = GetProcessDefaultStackSize();
817
818             if ((ulong)(uint)maxStackSize > defaultStackSize)
819             {
820                 try
821                 {
822                     SecurityPermission.Demand(PermissionType.FullTrust);
823                 }
824                 catch (SecurityException)
825                 {
826                     maxStackSize = (int)Math.Min(defaultStackSize, (ulong)(uint)int.MaxValue);
827                 }
828             }
829 #endif
830 #endif
831
832             ThreadHelper threadStartCallBack = new ThreadHelper(start);
833             if(start is ThreadStart)
834             {
835                 SetStart(new ThreadStart(threadStartCallBack.ThreadStart), maxStackSize);
836             }
837             else
838             {
839                 SetStart(new ParameterizedThreadStart(threadStartCallBack.ThreadStart), maxStackSize);
840             }                
841         }
842 #if !MONO
843         [SecurityCritical]
844         [ResourceExposure(ResourceScope.None)]
845         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
846         [SuppressUnmanagedCodeSecurity]
847         private static extern ulong GetProcessDefaultStackSize();
848
849         /*=========================================================================
850         ** PRIVATE Sets the IThreadable interface for the thread. Assumes that
851         ** start != null.
852         =========================================================================*/
853         [System.Security.SecurityCritical]  // auto-generated
854         [ResourceExposure(ResourceScope.None)]
855         [MethodImplAttribute(MethodImplOptions.InternalCall)]
856         private extern void SetStart(Delegate start, int maxStackSize);
857
858         /*=========================================================================
859         ** Clean up the thread when it goes away.
860         =========================================================================*/
861         [System.Security.SecuritySafeCritical]  // auto-generated
862         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
863         ~Thread()
864         {
865             // Delegate to the unmanaged portion.
866             InternalFinalize();
867         }
868
869         [System.Security.SecurityCritical]  // auto-generated
870         [ResourceExposure(ResourceScope.None)]
871         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
872         [MethodImplAttribute(MethodImplOptions.InternalCall)]
873         private extern void InternalFinalize();
874
875 #if FEATURE_COMINTEROP
876         [System.Security.SecurityCritical]  // auto-generated
877         [ResourceExposure(ResourceScope.None)]
878         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
879         [MethodImplAttribute(MethodImplOptions.InternalCall)]
880         public extern void DisableComObjectEagerCleanup();
881 #endif //FEATURE_COMINTEROP
882
883         /*=========================================================================
884         ** Return whether or not this thread is a background thread.  Background
885         ** threads do not affect when the Execution Engine shuts down.
886         **
887         ** Exceptions: ThreadStateException if the thread is dead.
888         =========================================================================*/
889         public bool IsBackground {
890             [System.Security.SecuritySafeCritical]  // auto-generated
891             get { return IsBackgroundNative(); }
892             [System.Security.SecuritySafeCritical]  // auto-generated
893             [HostProtection(SelfAffectingThreading=true)]
894             set { SetBackgroundNative(value); }
895         }
896         [System.Security.SecurityCritical]  // auto-generated
897         [ResourceExposure(ResourceScope.None)]
898         [MethodImplAttribute(MethodImplOptions.InternalCall)]
899         private extern bool IsBackgroundNative();
900         [System.Security.SecurityCritical]  // auto-generated
901         [ResourceExposure(ResourceScope.None)]
902         [MethodImplAttribute(MethodImplOptions.InternalCall)]
903         private extern void SetBackgroundNative(bool isBackground);
904
905
906         /*=========================================================================
907         ** Return the thread state as a consistent set of bits.  This is more
908         ** general then IsAlive or IsBackground.
909         =========================================================================*/
910         public ThreadState ThreadState {
911             [System.Security.SecuritySafeCritical]  // auto-generated
912             get { return (ThreadState)GetThreadStateNative(); }
913         }
914
915         [System.Security.SecurityCritical]  // auto-generated
916         [ResourceExposure(ResourceScope.None)]
917         [MethodImplAttribute(MethodImplOptions.InternalCall)]
918         private extern int GetThreadStateNative();
919
920 #if FEATURE_COMINTEROP_APARTMENT_SUPPORT
921         /*=========================================================================
922         ** An unstarted thread can be marked to indicate that it will host a
923         ** single-threaded or multi-threaded apartment.
924         **
925         ** Exceptions: ArgumentException if state is not a valid apartment state
926         **             (ApartmentSTA or ApartmentMTA).
927         =========================================================================*/
928         [Obsolete("The ApartmentState property has been deprecated.  Use GetApartmentState, SetApartmentState or TrySetApartmentState instead.", false)]
929         public ApartmentState ApartmentState
930         {
931             [System.Security.SecuritySafeCritical]  // auto-generated
932             get
933             {
934                 return (ApartmentState)GetApartmentStateNative();
935             }
936
937             [System.Security.SecuritySafeCritical]  // auto-generated
938             [HostProtection(Synchronization=true, SelfAffectingThreading=true)]
939             set
940             {
941                 SetApartmentStateNative((int)value, true);
942             }
943         }
944
945         [System.Security.SecuritySafeCritical]  // auto-generated
946         public ApartmentState GetApartmentState()
947         {
948             return (ApartmentState)GetApartmentStateNative();
949         }
950
951         [System.Security.SecuritySafeCritical]  // auto-generated
952         [HostProtection(Synchronization=true, SelfAffectingThreading=true)]
953         public bool TrySetApartmentState(ApartmentState state)
954         {
955             return SetApartmentStateHelper(state, false);
956         }
957
958         [System.Security.SecuritySafeCritical]  // auto-generated
959         [HostProtection(Synchronization=true, SelfAffectingThreading=true)]
960         public void SetApartmentState(ApartmentState state)
961         {
962             bool result = SetApartmentStateHelper(state, true);
963             if (!result)
964                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ApartmentStateSwitchFailed"));
965         }
966
967         [System.Security.SecurityCritical]  // auto-generated
968         private bool SetApartmentStateHelper(ApartmentState state, bool fireMDAOnMismatch)
969         {
970             ApartmentState retState = (ApartmentState)SetApartmentStateNative((int)state, fireMDAOnMismatch);
971
972             // Special case where we pass in Unknown and get back MTA.
973             //  Once we CoUninitialize the thread, the OS will still
974             //  report the thread as implicitly in the MTA if any
975             //  other thread in the process is CoInitialized.
976             if ((state == System.Threading.ApartmentState.Unknown) && (retState == System.Threading.ApartmentState.MTA))
977                 return true;
978             
979             if (retState != state)
980                 return false;
981
982             return true;            
983         }
984
985         [System.Security.SecurityCritical]  // auto-generated
986         [ResourceExposure(ResourceScope.None)]
987         [MethodImplAttribute(MethodImplOptions.InternalCall)]
988         private extern int GetApartmentStateNative();
989         [System.Security.SecurityCritical]  // auto-generated
990         [ResourceExposure(ResourceScope.None)]
991         [MethodImplAttribute(MethodImplOptions.InternalCall)]
992         private extern int SetApartmentStateNative(int state, bool fireMDAOnMismatch);
993         [System.Security.SecurityCritical]  // auto-generated
994         [ResourceExposure(ResourceScope.None)]
995         [MethodImplAttribute(MethodImplOptions.InternalCall)]
996         private extern void StartupSetApartmentStateInternal();
997 #endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT
998 #endif
999         /*=========================================================================
1000         ** Allocates an un-named data slot. The slot is allocated on ALL the
1001         ** threads.
1002         =========================================================================*/
1003         [HostProtection(SharedState=true, ExternalThreading=true)]
1004         public static LocalDataStoreSlot AllocateDataSlot()
1005         {
1006             return LocalDataStoreManager.AllocateDataSlot();
1007         }
1008
1009         /*=========================================================================
1010         ** Allocates a named data slot. The slot is allocated on ALL the
1011         ** threads.  Named data slots are "public" and can be manipulated by
1012         ** anyone.
1013         =========================================================================*/
1014         [HostProtection(SharedState=true, ExternalThreading=true)]
1015         public static LocalDataStoreSlot AllocateNamedDataSlot(String name)
1016         {
1017             return LocalDataStoreManager.AllocateNamedDataSlot(name);
1018         }
1019
1020         /*=========================================================================
1021         ** Looks up a named data slot. If the name has not been used, a new slot is
1022         ** allocated.  Named data slots are "public" and can be manipulated by
1023         ** anyone.
1024         =========================================================================*/
1025         [HostProtection(SharedState=true, ExternalThreading=true)]
1026         public static LocalDataStoreSlot GetNamedDataSlot(String name)
1027         {
1028             return LocalDataStoreManager.GetNamedDataSlot(name);
1029         }
1030
1031         /*=========================================================================
1032         ** Frees a named data slot. The slot is allocated on ALL the
1033         ** threads.  Named data slots are "public" and can be manipulated by
1034         ** anyone.
1035         =========================================================================*/
1036         [HostProtection(SharedState=true, ExternalThreading=true)]
1037         public static void FreeNamedDataSlot(String name)
1038         {
1039             LocalDataStoreManager.FreeNamedDataSlot(name);
1040         }
1041
1042         /*=========================================================================
1043         ** Retrieves the value from the specified slot on the current thread, for that thread's current domain.
1044         =========================================================================*/
1045         [HostProtection(SharedState=true, ExternalThreading=true)]
1046         [ResourceExposure(ResourceScope.AppDomain)]
1047         public static Object GetData(LocalDataStoreSlot slot)
1048         {
1049             LocalDataStoreHolder dls = s_LocalDataStore;
1050             if (dls == null)
1051             {
1052                 // Make sure to validate the slot even if we take the quick path
1053                 LocalDataStoreManager.ValidateSlot(slot);
1054                 return null;
1055             }
1056
1057             return dls.Store.GetData(slot);
1058         }
1059
1060         /*=========================================================================
1061         ** Sets the data in the specified slot on the currently running thread, for that thread's current domain.
1062         =========================================================================*/
1063         [HostProtection(SharedState=true, ExternalThreading=true)]
1064         [ResourceExposure(ResourceScope.AppDomain)]
1065         public static void SetData(LocalDataStoreSlot slot, Object data)
1066         {
1067             LocalDataStoreHolder dls = s_LocalDataStore;
1068
1069             // Create new DLS if one hasn't been created for this domain for this thread
1070             if (dls == null) {
1071                 dls = LocalDataStoreManager.CreateLocalDataStore();
1072                 s_LocalDataStore = dls;
1073             }
1074
1075             dls.Store.SetData(slot, data);
1076         }
1077 #if !MONO
1078
1079         // #threadCultureInfo
1080         //
1081         // Background:
1082         // In the desktop runtime, we allow a thread's cultures to travel with the thread
1083         // across AppDomain boundaries. Furthermore we update the native thread with the
1084         // culture of the managed thread. Because of security concerns and potential SxS
1085         // effects, in Silverlight we are making the changes listed below. 
1086         // 
1087         // Silverlight Changes:
1088         // - thread instance member cultures (CurrentCulture and CurrentUICulture) 
1089         //   confined within AppDomains
1090         // - changes to these properties don't affect the underlying native thread
1091         //
1092         // Ifdef:
1093         // FEATURE_LEAK_CULTURE_INFO      : CultureInfos can leak across AppDomains, not
1094         //                                  enabled in Silverlight
1095         // 
1096         // Implementation notes:
1097         // In Silverlight, culture members thread static (per Thread, per AppDomain). 
1098         //
1099         // Quirks:
1100         // An interesting side-effect of isolating cultures within an AppDomain is that we
1101         // now need to special case resource lookup for mscorlib, which transitions to the 
1102         // default domain to lookup resources. See Environment.cs for more details.
1103         // 
1104 #if FEATURE_LEAK_CULTURE_INFO
1105         [System.Security.SecurityCritical]  // auto-generated
1106         [ResourceExposure(ResourceScope.None)]
1107         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1108         static extern private bool nativeGetSafeCulture(Thread t, int appDomainId, bool isUI, ref CultureInfo safeCulture);
1109 #endif // FEATURE_LEAK_CULTURE_INFO
1110
1111         // As the culture can be customized object then we cannot hold any 
1112         // reference to it before we check if it is safe because the app domain 
1113         // owning this customized culture may get unloaded while executing this 
1114         // code. To achieve that we have to do the check using nativeGetSafeCulture 
1115         // as the thread cannot get interrupted during the FCALL. 
1116         // If the culture is safe (not customized or created in current app domain) 
1117         // then the FCALL will return a reference to that culture otherwise the 
1118         // FCALL will return failure. In case of failure we'll return the default culture.
1119         // If the app domain owning a customized culture that is set to teh thread and this
1120         // app domain get unloaded there is a code to clean up the culture from the thread
1121         // using the code in AppDomain::ReleaseDomainStores.
1122
1123         public CultureInfo CurrentUICulture {
1124             get {
1125                 Contract.Ensures(Contract.Result<CultureInfo>() != null);
1126 #if FEATURE_APPX
1127                 if(AppDomain.IsAppXModel()) {
1128                     return CultureInfo.GetCultureInfoForUserPreferredLanguageInAppX() ?? GetCurrentUICultureNoAppX();
1129                 } 
1130                 else 
1131 #endif
1132                 {
1133                     return GetCurrentUICultureNoAppX();
1134                 }
1135             }
1136
1137             [System.Security.SecuritySafeCritical]  // auto-generated
1138             [HostProtection(ExternalThreading=true)]
1139             set {
1140                 if (value == null) {
1141                     throw new ArgumentNullException("value");
1142                 }
1143                 Contract.EndContractBlock();
1144
1145                 //If they're trying to use a Culture with a name that we can't use in resource lookup,
1146                 //don't even let them set it on the thread.
1147                 CultureInfo.VerifyCultureName(value, true);
1148
1149                 // If you add more pre-conditions to this method, check to see if you also need to 
1150                 // add them to CultureInfo.DefaultThreadCurrentUICulture.set.
1151
1152 #if FEATURE_LEAK_CULTURE_INFO
1153                 if (nativeSetThreadUILocale(value.SortName) == false)
1154                 {
1155                     throw new ArgumentException(Environment.GetResourceString("Argument_InvalidResourceCultureName", value.Name));
1156                 }
1157                 value.StartCrossDomainTracking();
1158 #else
1159                 if (m_CurrentUICulture == null && m_CurrentCulture == null)
1160                     nativeInitCultureAccessors();
1161 #endif
1162
1163 #if FEATURE_LEGACYNETCF
1164                 if (CompatibilitySwitches.IsAppEarlierThanWindowsPhone8)
1165                 {
1166                     //
1167                     // NetCF had a 
1168
1169
1170
1171
1172
1173                     CultureInfo.SetCurrentUICultureQuirk(value);
1174                     return;
1175                 }
1176 #endif
1177                 if (!AppContextSwitches.NoAsyncCurrentCulture)
1178                 {
1179                     if (s_asyncLocalCurrentUICulture == null)
1180                     {
1181                         Interlocked.CompareExchange(ref s_asyncLocalCurrentUICulture, new AsyncLocal<CultureInfo>(AsyncLocalSetCurrentUICulture), null);
1182                     }
1183
1184                     // this one will set m_CurrentUICulture too
1185                     s_asyncLocalCurrentUICulture.Value = value;
1186                 }
1187                 else
1188                 {
1189                     m_CurrentUICulture = value;
1190                 }
1191             }
1192         }
1193
1194 #if FEATURE_LEAK_CULTURE_INFO
1195         [System.Security.SecuritySafeCritical]  // auto-generated
1196 #endif
1197         internal CultureInfo GetCurrentUICultureNoAppX() {
1198
1199             Contract.Ensures(Contract.Result<CultureInfo>() != null);
1200
1201             // Fetch a local copy of m_CurrentUICulture to 
1202             // avoid ----s that malicious user can introduce
1203             if (m_CurrentUICulture == null) {
1204                 CultureInfo appDomainDefaultUICulture = CultureInfo.DefaultThreadCurrentUICulture;
1205                 return (appDomainDefaultUICulture != null ? appDomainDefaultUICulture : CultureInfo.UserDefaultUICulture);
1206             }
1207
1208 #if FEATURE_LEAK_CULTURE_INFO
1209             CultureInfo culture = null;
1210
1211             if (!nativeGetSafeCulture(this, GetDomainID(), true, ref culture) || culture == null) {
1212                 return CultureInfo.UserDefaultUICulture;
1213             }
1214                 
1215             return culture;
1216 #else
1217             return m_CurrentUICulture;
1218 #endif
1219         }
1220
1221         // This returns the exposed context for a given context ID.
1222 #if FEATURE_LEAK_CULTURE_INFO
1223         [System.Security.SecurityCritical]  // auto-generated
1224         [ResourceExposure(ResourceScope.None)]
1225         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1226         static extern private bool nativeSetThreadUILocale(String locale);
1227 #endif
1228
1229         // As the culture can be customized object then we cannot hold any 
1230         // reference to it before we check if it is safe because the app domain 
1231         // owning this customized culture may get unloaded while executing this 
1232         // code. To achieve that we have to do the check using nativeGetSafeCulture 
1233         // as the thread cannot get interrupted during the FCALL. 
1234         // If the culture is safe (not customized or created in current app domain) 
1235         // then the FCALL will return a reference to that culture otherwise the 
1236         // FCALL will return failure. In case of failure we'll return the default culture.
1237         // If the app domain owning a customized culture that is set to teh thread and this
1238         // app domain get unloaded there is a code to clean up the culture from the thread
1239         // using the code in AppDomain::ReleaseDomainStores.
1240
1241         public CultureInfo CurrentCulture {
1242             get {
1243                 Contract.Ensures(Contract.Result<CultureInfo>() != null);
1244
1245 #if FEATURE_APPX
1246                 if(AppDomain.IsAppXModel()) {
1247                     return CultureInfo.GetCultureInfoForUserPreferredLanguageInAppX() ?? GetCurrentCultureNoAppX();
1248                 } 
1249                 else 
1250 #endif
1251                 {
1252                     return GetCurrentCultureNoAppX();
1253                 }
1254             }
1255
1256             [System.Security.SecuritySafeCritical]  // auto-generated
1257 #if FEATURE_LEAK_CULTURE_INFO
1258             [SecurityPermission(SecurityAction.Demand, ControlThread = true)]
1259 #endif
1260             set {
1261                 if (null==value) {
1262                     throw new ArgumentNullException("value");
1263                 }
1264                 Contract.EndContractBlock();
1265
1266                 // If you add more pre-conditions to this method, check to see if you also need to 
1267                 // add them to CultureInfo.DefaultThreadCurrentCulture.set.
1268
1269 #if FEATURE_LEAK_CULTURE_INFO
1270                 //If we can't set the nativeThreadLocale, we'll just let it stay
1271                 //at whatever value it had before.  This allows people who use
1272                 //just managed code not to be limited by the underlying OS.
1273                 CultureInfo.nativeSetThreadLocale(value.SortName);
1274                 value.StartCrossDomainTracking();
1275 #else
1276                 if (m_CurrentCulture == null && m_CurrentUICulture == null)
1277                     nativeInitCultureAccessors();
1278 #endif
1279
1280 #if FEATURE_LEGACYNETCF
1281                 if (CompatibilitySwitches.IsAppEarlierThanWindowsPhone8)
1282                 {
1283                     // See comment in CurrentUICulture setter
1284                     CultureInfo.SetCurrentCultureQuirk(value);
1285                     return;
1286                 }
1287 #endif
1288                 if (!AppContextSwitches.NoAsyncCurrentCulture)
1289                 {
1290                     if (s_asyncLocalCurrentCulture == null)
1291                     {
1292                         Interlocked.CompareExchange(ref s_asyncLocalCurrentCulture, new AsyncLocal<CultureInfo>(AsyncLocalSetCurrentCulture), null);
1293                     }
1294                     // this one will set m_CurrentCulture too
1295                     s_asyncLocalCurrentCulture.Value = value;
1296                 }
1297                 else
1298                 {
1299                     m_CurrentCulture = value;
1300                 }
1301             }
1302         }
1303
1304 #if FEATURE_LEAK_CULTURE_INFO
1305         [System.Security.SecuritySafeCritical]  // auto-generated
1306 #endif
1307         private CultureInfo GetCurrentCultureNoAppX() {
1308
1309             Contract.Ensures(Contract.Result<CultureInfo>() != null);
1310
1311             // Fetch a local copy of m_CurrentCulture to 
1312             // avoid ----s that malicious user can introduce
1313             if (m_CurrentCulture == null) {
1314                 CultureInfo appDomainDefaultCulture =  CultureInfo.DefaultThreadCurrentCulture;
1315                 return (appDomainDefaultCulture != null ? appDomainDefaultCulture : CultureInfo.UserDefaultCulture);
1316             }
1317
1318 #if FEATURE_LEAK_CULTURE_INFO
1319             CultureInfo culture = null;
1320               
1321             if (!nativeGetSafeCulture(this, GetDomainID(), false, ref culture) || culture == null) {
1322                 return CultureInfo.UserDefaultCulture;
1323             }
1324                 
1325             return culture;
1326 #else
1327             return m_CurrentCulture;
1328 #endif
1329
1330         }
1331
1332 #if! FEATURE_LEAK_CULTURE_INFO
1333         [System.Security.SecurityCritical]  // auto-generated
1334         [ResourceExposure(ResourceScope.None)]
1335         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
1336         [SuppressUnmanagedCodeSecurity]
1337         private static extern void nativeInitCultureAccessors();
1338 #endif
1339
1340         /*=============================================================*/
1341
1342         /*======================================================================
1343         **  Current thread context is stored in a slot in the thread local store
1344         **  CurrentContext gets the Context from the slot.
1345         ======================================================================*/
1346 #if FEATURE_REMOTING
1347         public static Context CurrentContext
1348         {
1349             [System.Security.SecurityCritical]  // auto-generated_required
1350             get
1351             {
1352                 return CurrentThread.GetCurrentContextInternal();
1353             }
1354         }
1355
1356         [System.Security.SecurityCritical]  // auto-generated
1357         internal Context GetCurrentContextInternal()
1358         {
1359             if (m_Context == null)
1360             {
1361                 m_Context = Context.DefaultContext;
1362             }
1363             return m_Context;
1364         }
1365 #endif        
1366
1367
1368 #if FEATURE_IMPERSONATION
1369         // Get and set thread's current principal (for role based security).
1370         public static IPrincipal CurrentPrincipal
1371         {
1372             [System.Security.SecuritySafeCritical]  // auto-generated
1373             get
1374             {
1375                 lock (CurrentThread)
1376                 {
1377                     IPrincipal principal = (IPrincipal)
1378                         CallContext.Principal;
1379                     if (principal == null)
1380                     {
1381                         principal = GetDomain().GetThreadPrincipal();
1382                         CallContext.Principal = principal;
1383                     }
1384                     return principal;
1385                 }
1386             }
1387
1388             [System.Security.SecuritySafeCritical]  // auto-generated
1389             [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.ControlPrincipal)]
1390             set
1391             {
1392                 CallContext.Principal = value;
1393             }
1394         }
1395
1396         // Private routine called from unmanaged code to set an initial
1397         // principal for a newly created thread.
1398         [System.Security.SecurityCritical]  // auto-generated
1399         private void SetPrincipalInternal(IPrincipal principal)
1400         {
1401             GetMutableExecutionContext().LogicalCallContext.SecurityData.Principal = principal;
1402         }
1403 #endif // FEATURE_IMPERSONATION
1404
1405 #if FEATURE_REMOTING   
1406
1407         // This returns the exposed context for a given context ID.
1408         [System.Security.SecurityCritical]  // auto-generated
1409         [ResourceExposure(ResourceScope.None)]
1410         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1411         internal static extern Context GetContextInternal(IntPtr id);
1412
1413         [System.Security.SecurityCritical]  // auto-generated
1414         [ResourceExposure(ResourceScope.None)]
1415         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1416         internal extern Object InternalCrossContextCallback(Context ctx, IntPtr ctxID, Int32 appDomainID, InternalCrossContextDelegate ftnToCall, Object[] args);
1417
1418         [System.Security.SecurityCritical]  // auto-generated
1419         internal Object InternalCrossContextCallback(Context ctx, InternalCrossContextDelegate ftnToCall, Object[] args)
1420         {
1421             return InternalCrossContextCallback(ctx, ctx.InternalContextID, 0, ftnToCall, args);
1422         }
1423
1424         // CompleteCrossContextCallback is called by the EE after transitioning to the requested context
1425         private static Object CompleteCrossContextCallback(InternalCrossContextDelegate ftnToCall, Object[] args)
1426         {
1427             return ftnToCall(args);
1428         }
1429 #endif // FEATURE_REMOTING
1430
1431         /*======================================================================
1432         ** Returns the current domain in which current thread is running.
1433         ======================================================================*/
1434
1435         [System.Security.SecurityCritical]  // auto-generated
1436         [ResourceExposure(ResourceScope.None)]
1437         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1438         private static extern AppDomain GetDomainInternal();
1439         [System.Security.SecurityCritical]  // auto-generated
1440         [ResourceExposure(ResourceScope.None)]
1441         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1442         private static extern AppDomain GetFastDomainInternal();
1443
1444         [System.Security.SecuritySafeCritical]  // auto-generated
1445         public static AppDomain GetDomain()
1446         {
1447             Contract.Ensures(Contract.Result<AppDomain>() != null);
1448
1449
1450             AppDomain ad;
1451             ad = GetFastDomainInternal();
1452             if (ad == null)
1453                 ad = GetDomainInternal();
1454
1455 #if FEATURE_REMOTING        
1456             Contract.Assert(CurrentThread.m_Context == null || CurrentThread.m_Context.AppDomain == ad, "AppDomains on the managed & unmanaged threads should match");
1457 #endif
1458             return ad;
1459         }
1460
1461
1462         /*
1463          *  This returns a unique id to identify an appdomain.
1464          */
1465         public static int GetDomainID()
1466         {
1467             return GetDomain().GetId();
1468         }
1469
1470
1471         // Retrieves the name of the thread.
1472         //
1473         public  String Name {
1474             get {
1475                 return m_Name;
1476
1477             }
1478             [System.Security.SecuritySafeCritical]  // auto-generated
1479             [HostProtection(ExternalThreading=true)]
1480             set {
1481                 lock(this) {
1482                     if (m_Name != null)
1483                         throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_WriteOnce"));
1484                     m_Name = value;
1485
1486                     InformThreadNameChange(GetNativeHandle(), value, (value != null) ? value.Length : 0);
1487                 }
1488             }
1489         }
1490
1491         [System.Security.SecurityCritical]  // auto-generated
1492         [ResourceExposure(ResourceScope.None)]
1493         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
1494         [SuppressUnmanagedCodeSecurity]
1495         private static extern void InformThreadNameChange(ThreadHandle t, String name, int len);
1496
1497         internal Object AbortReason {
1498             [System.Security.SecurityCritical]  // auto-generated
1499             get {
1500                 object result = null;
1501                 try
1502                 {
1503                     result = GetAbortReason();
1504                 }
1505                 catch (Exception e)
1506                 {
1507                     throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ExceptionStateCrossAppDomain"), e);
1508                 }
1509                 return result;
1510             }
1511             [System.Security.SecurityCritical]  // auto-generated
1512             set { SetAbortReason(value); }
1513         }
1514
1515         /*
1516          *  This marks the beginning of a critical code region.
1517          */
1518         [System.Security.SecuritySafeCritical]  // auto-generated
1519         [HostProtection(Synchronization=true, ExternalThreading=true)]
1520         [ResourceExposure(ResourceScope.None)]
1521         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1522         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
1523         public static extern void BeginCriticalRegion();
1524
1525         /*
1526          *  This marks the end of a critical code region.
1527          */
1528         [System.Security.SecuritySafeCritical]  // auto-generated
1529         [HostProtection(Synchronization=true, ExternalThreading=true)]
1530         [ResourceExposure(ResourceScope.None)]
1531         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1532         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
1533         public static extern void EndCriticalRegion();
1534
1535         /*
1536          *  This marks the beginning of a code region that requires thread affinity.
1537          */
1538         [System.Security.SecurityCritical]  // auto-generated_required
1539         [ResourceExposure(ResourceScope.None)]
1540         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1541         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
1542         public static extern void BeginThreadAffinity();
1543
1544         /*
1545          *  This marks the end of a code region that requires thread affinity.
1546          */
1547         [System.Security.SecurityCritical]  // auto-generated_required
1548         [ResourceExposure(ResourceScope.None)]
1549         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1550         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
1551         public static extern void EndThreadAffinity();
1552
1553         /*=========================================================================
1554         ** Volatile Read & Write and MemoryBarrier methods.
1555         ** Provides the ability to read and write values ensuring that the values
1556         ** are read/written each time they are accessed.
1557         =========================================================================*/
1558
1559         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1560         public static byte VolatileRead(ref byte address)
1561         {
1562             byte ret = address;
1563             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1564             return ret;
1565         }
1566
1567         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1568         public static short VolatileRead(ref short address)
1569         {
1570             short ret = address;
1571             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1572             return ret;
1573         }
1574
1575         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1576         public static int VolatileRead(ref int address)
1577         {
1578             int ret = address;
1579             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1580             return ret;
1581         }
1582
1583         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1584         public static long VolatileRead(ref long address)
1585         {
1586             long ret = address;
1587             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1588             return ret;
1589         }
1590
1591         [CLSCompliant(false)]
1592         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1593         public static sbyte VolatileRead(ref sbyte address)
1594         {
1595             sbyte ret = address;
1596             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1597             return ret;
1598         }
1599
1600         [CLSCompliant(false)]
1601         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1602         public static ushort VolatileRead(ref ushort address)
1603         {
1604             ushort ret = address;
1605             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1606             return ret;
1607         }
1608
1609         [CLSCompliant(false)]
1610         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1611         public static uint VolatileRead(ref uint address)
1612         {
1613             uint ret = address;
1614             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1615             return ret;
1616         }
1617
1618         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1619         public static IntPtr VolatileRead(ref IntPtr address)
1620         {
1621             IntPtr ret = address;
1622             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1623             return ret;
1624         }
1625
1626         [CLSCompliant(false)]
1627         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1628         public static UIntPtr VolatileRead(ref UIntPtr address)
1629         {
1630             UIntPtr ret = address;
1631             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1632             return ret;
1633         }
1634
1635         [CLSCompliant(false)]
1636         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1637         public static ulong VolatileRead(ref ulong address)
1638         {
1639             ulong ret = address;
1640             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1641             return ret;
1642         }
1643
1644         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1645         public static float VolatileRead(ref float address)
1646         {
1647             float ret = address;
1648             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1649             return ret;
1650         }
1651
1652         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1653         public static double VolatileRead(ref double address)
1654         {
1655             double ret = address;
1656             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1657             return ret;
1658         }
1659
1660         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1661         public static Object VolatileRead(ref Object address)
1662         {
1663             Object ret = address;
1664             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1665             return ret;
1666         }
1667
1668         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1669         public static void VolatileWrite(ref byte address, byte value)
1670         {
1671             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1672             address = value;
1673         }
1674
1675         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1676         public static void VolatileWrite(ref short address, short value)
1677         {
1678             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1679             address = value;
1680         }
1681
1682         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1683         public static void VolatileWrite(ref int address, int value)
1684         {
1685             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1686             address = value;
1687         }
1688
1689         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1690         public static void VolatileWrite(ref long address, long value)
1691         {
1692             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1693             address = value;
1694         }
1695
1696         [CLSCompliant(false)]
1697         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1698         public static void VolatileWrite(ref sbyte address, sbyte value)
1699         {
1700             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1701             address = value;
1702         }
1703
1704         [CLSCompliant(false)]
1705         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1706         public static void VolatileWrite(ref ushort address, ushort value)
1707         {
1708             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1709             address = value;
1710         }
1711
1712         [CLSCompliant(false)]
1713         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1714         public static void VolatileWrite(ref uint address, uint value)
1715         {
1716             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1717             address = value;
1718         }
1719
1720         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1721         public static void VolatileWrite(ref IntPtr address, IntPtr value)
1722         {
1723             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1724             address = value;
1725         }
1726
1727         [CLSCompliant(false)]
1728         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1729         public static void VolatileWrite(ref UIntPtr address, UIntPtr value)
1730         {
1731             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1732             address = value;
1733         }
1734
1735         [CLSCompliant(false)]
1736         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1737         public static void VolatileWrite(ref ulong address, ulong value)
1738         {
1739             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1740             address = value;
1741         }
1742
1743         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1744         public static void VolatileWrite(ref float address, float value)
1745         {
1746             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1747             address = value;
1748         }
1749
1750         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1751         public static void VolatileWrite(ref double address, double value)
1752         {
1753             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1754             address = value;
1755         }
1756
1757         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1758         public static void VolatileWrite(ref Object address, Object value)
1759         {
1760             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1761             address = value;
1762         }
1763 #endif
1764         [System.Security.SecuritySafeCritical]  // auto-generated
1765         [ResourceExposure(ResourceScope.None)]
1766         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1767         public static extern void MemoryBarrier();
1768
1769         private static LocalDataStoreMgr LocalDataStoreManager
1770         {
1771             get 
1772             {
1773                 if (s_LocalDataStoreMgr == null)
1774                 {
1775                     Interlocked.CompareExchange(ref s_LocalDataStoreMgr, new LocalDataStoreMgr(), null);    
1776                 }
1777
1778                 return s_LocalDataStoreMgr;
1779             }
1780         }
1781
1782 #if !FEATURE_CORECLR && !MOBILE
1783         void _Thread.GetTypeInfoCount(out uint pcTInfo)
1784         {
1785             throw new NotImplementedException();
1786         }
1787
1788         void _Thread.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
1789         {
1790             throw new NotImplementedException();
1791         }
1792
1793         void _Thread.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
1794         {
1795             throw new NotImplementedException();
1796         }
1797
1798         void _Thread.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
1799         {
1800             throw new NotImplementedException();
1801         }
1802 #endif
1803
1804 #if !MONO
1805         // Helper function to set the AbortReason for a thread abort.
1806         //  Checks that they're not alredy set, and then atomically updates
1807         //  the reason info (object + ADID).
1808         [System.Security.SecurityCritical]  // auto-generated
1809         [ResourceExposure(ResourceScope.None)]
1810         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1811         internal extern void SetAbortReason(Object o);
1812     
1813         // Helper function to retrieve the AbortReason from a thread
1814         //  abort.  Will perform cross-AppDomain marshalling if the object
1815         //  lives in a different AppDomain from the requester.
1816         [System.Security.SecurityCritical]  // auto-generated
1817         [ResourceExposure(ResourceScope.None)]
1818         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1819         internal extern Object GetAbortReason();
1820     
1821         // Helper function to clear the AbortReason.  Takes care of
1822         //  AppDomain related cleanup if required.
1823         [System.Security.SecurityCritical]  // auto-generated
1824         [ResourceExposure(ResourceScope.None)]
1825         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1826         internal extern void ClearAbortReason();
1827 #endif
1828
1829     } // End of class Thread
1830
1831     // declaring a local var of this enum type and passing it by ref into a function that needs to do a
1832     // stack crawl will both prevent inlining of the calle and pass an ESP point to stack crawl to
1833     // Declaring these in EH clauses is illegal; they must declared in the main method body
1834     [Serializable]
1835     internal enum StackCrawlMark
1836     {
1837         LookForMe = 0,
1838         LookForMyCaller = 1,
1839         LookForMyCallersCaller = 2,
1840         LookForThread = 3
1841     }
1842
1843 }