Thread.Interrupt is not dependent on MONO_FEATURE_THREAD_SUSPEND_RESUME.
[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) || MONO_FEATURE_THREAD_ABORT
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 #endif
582 #if (!FEATURE_CORECLR && !MONO) || MONO_FEATURE_THREAD_SUSPEND_RESUME
583         /*=========================================================================
584         ** Suspends the thread. If the thread is already suspended, this call has
585         ** no effect.
586         **
587         ** Exceptions: ThreadStateException if the thread has not been started or
588         **             it is dead.
589         =========================================================================*/
590         [System.Security.SecuritySafeCritical]  // auto-generated
591         [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)]
592         [SecurityPermission(SecurityAction.Demand, ControlThread=true)]
593         public void Suspend() { SuspendInternal(); }
594
595         // Internal helper (since we can't place security demands on
596         // ecalls/fcalls).
597         [System.Security.SecurityCritical]  // auto-generated
598         [ResourceExposure(ResourceScope.None)]
599         [MethodImplAttribute(MethodImplOptions.InternalCall)]
600         private extern void SuspendInternal();
601
602         /*=========================================================================
603         ** Resumes a thread that has been suspended.
604         **
605         ** Exceptions: ThreadStateException if the thread has not been started or
606         **             it is dead or it isn't in the suspended state.
607         =========================================================================*/
608         [System.Security.SecuritySafeCritical]  // auto-generated
609         [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)]
610         [SecurityPermission(SecurityAction.Demand, ControlThread=true)]
611         public void Resume() { ResumeInternal(); }
612
613         // Internal helper (since we can't place security demands on
614         // ecalls/fcalls).
615         [System.Security.SecurityCritical]  // auto-generated
616         [ResourceExposure(ResourceScope.None)]
617         [MethodImplAttribute(MethodImplOptions.InternalCall)]
618         private extern void ResumeInternal();
619 #endif
620
621 #if !FEATURE_CORECLR || MONO
622         /*=========================================================================
623         ** Interrupts a thread that is inside a Wait(), Sleep() or Join().  If that
624         ** thread is not currently blocked in that manner, it will be interrupted
625         ** when it next begins to block.
626         =========================================================================*/
627         [System.Security.SecuritySafeCritical]  // auto-generated
628         [SecurityPermission(SecurityAction.Demand, ControlThread=true)]
629         public void Interrupt() { InterruptInternal(); }
630
631         // Internal helper (since we can't place security demands on
632         // ecalls/fcalls).
633         [System.Security.SecurityCritical]  // auto-generated
634         [ResourceExposure(ResourceScope.None)]
635         [MethodImplAttribute(MethodImplOptions.InternalCall)]
636         private extern void InterruptInternal();
637 #endif
638
639         /*=========================================================================
640         ** Returns the priority of the thread.
641         **
642         ** Exceptions: ThreadStateException if the thread is dead.
643         =========================================================================*/
644
645         public ThreadPriority Priority {
646             [System.Security.SecuritySafeCritical]  // auto-generated
647             get { return (ThreadPriority)GetPriorityNative(); }
648             [System.Security.SecuritySafeCritical]  // auto-generated
649             [HostProtection(SelfAffectingThreading=true)]
650             set { SetPriorityNative((int)value); }
651         }
652         [System.Security.SecurityCritical]  // auto-generated
653         [ResourceExposure(ResourceScope.None)]
654         [MethodImplAttribute(MethodImplOptions.InternalCall)]
655         private extern int GetPriorityNative();
656         [System.Security.SecurityCritical]  // auto-generated
657         [ResourceExposure(ResourceScope.None)]
658         [MethodImplAttribute(MethodImplOptions.InternalCall)]
659         private extern void SetPriorityNative(int priority);
660 #if !MONO
661         /*=========================================================================
662         ** Returns true if the thread has been started and is not dead.
663         =========================================================================*/
664         public extern bool IsAlive {
665             [System.Security.SecuritySafeCritical]  // auto-generated
666             [MethodImpl(MethodImplOptions.InternalCall)]
667             get;
668         }
669
670         /*=========================================================================
671         ** Returns true if the thread is a threadpool thread.
672         =========================================================================*/
673         public extern bool IsThreadPoolThread {
674             [System.Security.SecuritySafeCritical]  // auto-generated
675             [MethodImpl(MethodImplOptions.InternalCall)]
676             get;
677         }
678 #endif
679         /*=========================================================================
680         ** Waits for the thread to die or for timeout milliseconds to elapse.
681         ** Returns true if the thread died, or false if the wait timed out. If
682         ** Timeout.Infinite is given as the parameter, no timeout will occur.
683         **
684         ** Exceptions: ArgumentException if timeout < 0.
685         **             ThreadInterruptedException if the thread is interrupted while waiting.
686         **             ThreadStateException if the thread has not been started yet.
687         =========================================================================*/
688         [System.Security.SecurityCritical]
689         [ResourceExposure(ResourceScope.None)]
690         [MethodImplAttribute(MethodImplOptions.InternalCall)]
691         private extern bool JoinInternal(int millisecondsTimeout);
692
693         [System.Security.SecuritySafeCritical]
694         [HostProtection(Synchronization=true, ExternalThreading=true)]
695         public void Join()
696         {
697             JoinInternal(Timeout.Infinite);
698         }
699
700         [System.Security.SecuritySafeCritical]
701         [HostProtection(Synchronization=true, ExternalThreading=true)]
702         public bool Join(int millisecondsTimeout)
703         {
704 #if MONO
705             if (millisecondsTimeout < Timeout.Infinite)
706                 throw new ArgumentOutOfRangeException("millisecondsTimeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
707 #endif
708             return JoinInternal(millisecondsTimeout);
709         }
710
711         [HostProtection(Synchronization=true, ExternalThreading=true)]
712         public bool Join(TimeSpan timeout)
713         {
714             long tm = (long)timeout.TotalMilliseconds;
715             if (tm < -1 || tm > (long) Int32.MaxValue)
716                 throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
717
718             return Join((int)tm);
719         }
720
721         /*=========================================================================
722         ** Suspends the current thread for timeout milliseconds. If timeout == 0,
723         ** forces the thread to give up the remainer of its timeslice.  If timeout
724         ** == Timeout.Infinite, no timeout will occur.
725         **
726         ** Exceptions: ArgumentException if timeout < 0.
727         **             ThreadInterruptedException if the thread is interrupted while sleeping.
728         =========================================================================*/
729         [System.Security.SecurityCritical]  // auto-generated
730         [ResourceExposure(ResourceScope.None)]
731         [MethodImplAttribute(MethodImplOptions.InternalCall)]
732         private static extern void SleepInternal(int millisecondsTimeout);
733
734         [System.Security.SecuritySafeCritical]  // auto-generated
735         public static void Sleep(int millisecondsTimeout)
736         {
737 #if MONO
738             if (millisecondsTimeout < Timeout.Infinite)
739                 throw new ArgumentOutOfRangeException("millisecondsTimeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
740 #endif
741             SleepInternal(millisecondsTimeout);
742 #if !MONO
743             // Ensure we don't return to app code when the pause is underway
744             if(AppDomainPauseManager.IsPaused)
745                 AppDomainPauseManager.ResumeEvent.WaitOneWithoutFAS();
746 #endif
747         }
748
749         public static void Sleep(TimeSpan timeout)
750         {
751             long tm = (long)timeout.TotalMilliseconds;
752             if (tm < -1 || tm > (long) Int32.MaxValue)
753                 throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
754             Sleep((int)tm);
755         }
756
757 #if !MONO
758         /* wait for a length of time proportial to 'iterations'.  Each iteration is should
759            only take a few machine instructions.  Calling this API is preferable to coding
760            a explict busy loop because the hardware can be informed that it is busy waiting. */
761
762         [System.Security.SecurityCritical]  // auto-generated
763         [MethodImplAttribute(MethodImplOptions.InternalCall),
764          HostProtection(Synchronization=true,ExternalThreading=true),
765          ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success),
766          ResourceExposure(ResourceScope.None)]
767         private static extern void SpinWaitInternal(int iterations);
768
769         [System.Security.SecuritySafeCritical]  // auto-generated
770         [HostProtection(Synchronization=true,ExternalThreading=true),
771          ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
772         public static void SpinWait(int iterations)
773         {
774             SpinWaitInternal(iterations);
775         }
776 #endif
777         [System.Security.SecurityCritical]  // auto-generated
778         [ResourceExposure(ResourceScope.None)]
779         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
780         [SuppressUnmanagedCodeSecurity]
781         [HostProtection(Synchronization = true, ExternalThreading = true),
782          ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
783         private static extern bool YieldInternal();
784
785         [System.Security.SecuritySafeCritical]  // auto-generated
786         [HostProtection(Synchronization = true, ExternalThreading = true),
787          ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
788         public static bool Yield()
789         {
790             return YieldInternal();
791         }
792
793 #if !MONO
794         public static Thread CurrentThread {
795             [System.Security.SecuritySafeCritical]  // auto-generated
796             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
797             get {
798                 Contract.Ensures(Contract.Result<Thread>() != null);
799                 return GetCurrentThreadNative();
800             }
801         }
802         [System.Security.SecurityCritical]  // auto-generated
803         [ResourceExposure(ResourceScope.None)]
804         [MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
805         private static extern Thread GetCurrentThreadNative();
806 #endif
807         [System.Security.SecurityCritical]  // auto-generated
808         private void SetStartHelper(Delegate start, int maxStackSize)
809         {
810 #if MONO
811             maxStackSize = GetProcessDefaultStackSize(maxStackSize);
812 #else
813 #if FEATURE_CORECLR
814             // We only support default stacks in CoreCLR
815             Contract.Assert(maxStackSize == 0);
816 #else
817             // Only fully-trusted code is allowed to create "large" stacks.  Partial-trust falls back to
818             // the default stack size.
819             ulong defaultStackSize = GetProcessDefaultStackSize();
820
821             if ((ulong)(uint)maxStackSize > defaultStackSize)
822             {
823                 try
824                 {
825                     SecurityPermission.Demand(PermissionType.FullTrust);
826                 }
827                 catch (SecurityException)
828                 {
829                     maxStackSize = (int)Math.Min(defaultStackSize, (ulong)(uint)int.MaxValue);
830                 }
831             }
832 #endif
833 #endif
834
835             ThreadHelper threadStartCallBack = new ThreadHelper(start);
836             if(start is ThreadStart)
837             {
838                 SetStart(new ThreadStart(threadStartCallBack.ThreadStart), maxStackSize);
839             }
840             else
841             {
842                 SetStart(new ParameterizedThreadStart(threadStartCallBack.ThreadStart), maxStackSize);
843             }                
844         }
845 #if !MONO
846         [SecurityCritical]
847         [ResourceExposure(ResourceScope.None)]
848         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
849         [SuppressUnmanagedCodeSecurity]
850         private static extern ulong GetProcessDefaultStackSize();
851
852         /*=========================================================================
853         ** PRIVATE Sets the IThreadable interface for the thread. Assumes that
854         ** start != null.
855         =========================================================================*/
856         [System.Security.SecurityCritical]  // auto-generated
857         [ResourceExposure(ResourceScope.None)]
858         [MethodImplAttribute(MethodImplOptions.InternalCall)]
859         private extern void SetStart(Delegate start, int maxStackSize);
860
861         /*=========================================================================
862         ** Clean up the thread when it goes away.
863         =========================================================================*/
864         [System.Security.SecuritySafeCritical]  // auto-generated
865         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
866         ~Thread()
867         {
868             // Delegate to the unmanaged portion.
869             InternalFinalize();
870         }
871
872         [System.Security.SecurityCritical]  // auto-generated
873         [ResourceExposure(ResourceScope.None)]
874         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
875         [MethodImplAttribute(MethodImplOptions.InternalCall)]
876         private extern void InternalFinalize();
877
878 #if FEATURE_COMINTEROP
879         [System.Security.SecurityCritical]  // auto-generated
880         [ResourceExposure(ResourceScope.None)]
881         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
882         [MethodImplAttribute(MethodImplOptions.InternalCall)]
883         public extern void DisableComObjectEagerCleanup();
884 #endif //FEATURE_COMINTEROP
885
886         /*=========================================================================
887         ** Return whether or not this thread is a background thread.  Background
888         ** threads do not affect when the Execution Engine shuts down.
889         **
890         ** Exceptions: ThreadStateException if the thread is dead.
891         =========================================================================*/
892         public bool IsBackground {
893             [System.Security.SecuritySafeCritical]  // auto-generated
894             get { return IsBackgroundNative(); }
895             [System.Security.SecuritySafeCritical]  // auto-generated
896             [HostProtection(SelfAffectingThreading=true)]
897             set { SetBackgroundNative(value); }
898         }
899         [System.Security.SecurityCritical]  // auto-generated
900         [ResourceExposure(ResourceScope.None)]
901         [MethodImplAttribute(MethodImplOptions.InternalCall)]
902         private extern bool IsBackgroundNative();
903         [System.Security.SecurityCritical]  // auto-generated
904         [ResourceExposure(ResourceScope.None)]
905         [MethodImplAttribute(MethodImplOptions.InternalCall)]
906         private extern void SetBackgroundNative(bool isBackground);
907
908
909         /*=========================================================================
910         ** Return the thread state as a consistent set of bits.  This is more
911         ** general then IsAlive or IsBackground.
912         =========================================================================*/
913         public ThreadState ThreadState {
914             [System.Security.SecuritySafeCritical]  // auto-generated
915             get { return (ThreadState)GetThreadStateNative(); }
916         }
917
918         [System.Security.SecurityCritical]  // auto-generated
919         [ResourceExposure(ResourceScope.None)]
920         [MethodImplAttribute(MethodImplOptions.InternalCall)]
921         private extern int GetThreadStateNative();
922
923 #if FEATURE_COMINTEROP_APARTMENT_SUPPORT
924         /*=========================================================================
925         ** An unstarted thread can be marked to indicate that it will host a
926         ** single-threaded or multi-threaded apartment.
927         **
928         ** Exceptions: ArgumentException if state is not a valid apartment state
929         **             (ApartmentSTA or ApartmentMTA).
930         =========================================================================*/
931         [Obsolete("The ApartmentState property has been deprecated.  Use GetApartmentState, SetApartmentState or TrySetApartmentState instead.", false)]
932         public ApartmentState ApartmentState
933         {
934             [System.Security.SecuritySafeCritical]  // auto-generated
935             get
936             {
937                 return (ApartmentState)GetApartmentStateNative();
938             }
939
940             [System.Security.SecuritySafeCritical]  // auto-generated
941             [HostProtection(Synchronization=true, SelfAffectingThreading=true)]
942             set
943             {
944                 SetApartmentStateNative((int)value, true);
945             }
946         }
947
948         [System.Security.SecuritySafeCritical]  // auto-generated
949         public ApartmentState GetApartmentState()
950         {
951             return (ApartmentState)GetApartmentStateNative();
952         }
953
954         [System.Security.SecuritySafeCritical]  // auto-generated
955         [HostProtection(Synchronization=true, SelfAffectingThreading=true)]
956         public bool TrySetApartmentState(ApartmentState state)
957         {
958             return SetApartmentStateHelper(state, false);
959         }
960
961         [System.Security.SecuritySafeCritical]  // auto-generated
962         [HostProtection(Synchronization=true, SelfAffectingThreading=true)]
963         public void SetApartmentState(ApartmentState state)
964         {
965             bool result = SetApartmentStateHelper(state, true);
966             if (!result)
967                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ApartmentStateSwitchFailed"));
968         }
969
970         [System.Security.SecurityCritical]  // auto-generated
971         private bool SetApartmentStateHelper(ApartmentState state, bool fireMDAOnMismatch)
972         {
973             ApartmentState retState = (ApartmentState)SetApartmentStateNative((int)state, fireMDAOnMismatch);
974
975             // Special case where we pass in Unknown and get back MTA.
976             //  Once we CoUninitialize the thread, the OS will still
977             //  report the thread as implicitly in the MTA if any
978             //  other thread in the process is CoInitialized.
979             if ((state == System.Threading.ApartmentState.Unknown) && (retState == System.Threading.ApartmentState.MTA))
980                 return true;
981             
982             if (retState != state)
983                 return false;
984
985             return true;            
986         }
987
988         [System.Security.SecurityCritical]  // auto-generated
989         [ResourceExposure(ResourceScope.None)]
990         [MethodImplAttribute(MethodImplOptions.InternalCall)]
991         private extern int GetApartmentStateNative();
992         [System.Security.SecurityCritical]  // auto-generated
993         [ResourceExposure(ResourceScope.None)]
994         [MethodImplAttribute(MethodImplOptions.InternalCall)]
995         private extern int SetApartmentStateNative(int state, bool fireMDAOnMismatch);
996         [System.Security.SecurityCritical]  // auto-generated
997         [ResourceExposure(ResourceScope.None)]
998         [MethodImplAttribute(MethodImplOptions.InternalCall)]
999         private extern void StartupSetApartmentStateInternal();
1000 #endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT
1001 #endif
1002         /*=========================================================================
1003         ** Allocates an un-named data slot. The slot is allocated on ALL the
1004         ** threads.
1005         =========================================================================*/
1006         [HostProtection(SharedState=true, ExternalThreading=true)]
1007         public static LocalDataStoreSlot AllocateDataSlot()
1008         {
1009             return LocalDataStoreManager.AllocateDataSlot();
1010         }
1011
1012         /*=========================================================================
1013         ** Allocates a named data slot. The slot is allocated on ALL the
1014         ** threads.  Named data slots are "public" and can be manipulated by
1015         ** anyone.
1016         =========================================================================*/
1017         [HostProtection(SharedState=true, ExternalThreading=true)]
1018         public static LocalDataStoreSlot AllocateNamedDataSlot(String name)
1019         {
1020             return LocalDataStoreManager.AllocateNamedDataSlot(name);
1021         }
1022
1023         /*=========================================================================
1024         ** Looks up a named data slot. If the name has not been used, a new slot is
1025         ** allocated.  Named data slots are "public" and can be manipulated by
1026         ** anyone.
1027         =========================================================================*/
1028         [HostProtection(SharedState=true, ExternalThreading=true)]
1029         public static LocalDataStoreSlot GetNamedDataSlot(String name)
1030         {
1031             return LocalDataStoreManager.GetNamedDataSlot(name);
1032         }
1033
1034         /*=========================================================================
1035         ** Frees a named data slot. The slot is allocated on ALL the
1036         ** threads.  Named data slots are "public" and can be manipulated by
1037         ** anyone.
1038         =========================================================================*/
1039         [HostProtection(SharedState=true, ExternalThreading=true)]
1040         public static void FreeNamedDataSlot(String name)
1041         {
1042             LocalDataStoreManager.FreeNamedDataSlot(name);
1043         }
1044
1045         /*=========================================================================
1046         ** Retrieves the value from the specified slot on the current thread, for that thread's current domain.
1047         =========================================================================*/
1048         [HostProtection(SharedState=true, ExternalThreading=true)]
1049         [ResourceExposure(ResourceScope.AppDomain)]
1050         public static Object GetData(LocalDataStoreSlot slot)
1051         {
1052             LocalDataStoreHolder dls = s_LocalDataStore;
1053             if (dls == null)
1054             {
1055                 // Make sure to validate the slot even if we take the quick path
1056                 LocalDataStoreManager.ValidateSlot(slot);
1057                 return null;
1058             }
1059
1060             return dls.Store.GetData(slot);
1061         }
1062
1063         /*=========================================================================
1064         ** Sets the data in the specified slot on the currently running thread, for that thread's current domain.
1065         =========================================================================*/
1066         [HostProtection(SharedState=true, ExternalThreading=true)]
1067         [ResourceExposure(ResourceScope.AppDomain)]
1068         public static void SetData(LocalDataStoreSlot slot, Object data)
1069         {
1070             LocalDataStoreHolder dls = s_LocalDataStore;
1071
1072             // Create new DLS if one hasn't been created for this domain for this thread
1073             if (dls == null) {
1074                 dls = LocalDataStoreManager.CreateLocalDataStore();
1075                 s_LocalDataStore = dls;
1076             }
1077
1078             dls.Store.SetData(slot, data);
1079         }
1080 #if !MONO
1081
1082         // #threadCultureInfo
1083         //
1084         // Background:
1085         // In the desktop runtime, we allow a thread's cultures to travel with the thread
1086         // across AppDomain boundaries. Furthermore we update the native thread with the
1087         // culture of the managed thread. Because of security concerns and potential SxS
1088         // effects, in Silverlight we are making the changes listed below. 
1089         // 
1090         // Silverlight Changes:
1091         // - thread instance member cultures (CurrentCulture and CurrentUICulture) 
1092         //   confined within AppDomains
1093         // - changes to these properties don't affect the underlying native thread
1094         //
1095         // Ifdef:
1096         // FEATURE_LEAK_CULTURE_INFO      : CultureInfos can leak across AppDomains, not
1097         //                                  enabled in Silverlight
1098         // 
1099         // Implementation notes:
1100         // In Silverlight, culture members thread static (per Thread, per AppDomain). 
1101         //
1102         // Quirks:
1103         // An interesting side-effect of isolating cultures within an AppDomain is that we
1104         // now need to special case resource lookup for mscorlib, which transitions to the 
1105         // default domain to lookup resources. See Environment.cs for more details.
1106         // 
1107 #if FEATURE_LEAK_CULTURE_INFO
1108         [System.Security.SecurityCritical]  // auto-generated
1109         [ResourceExposure(ResourceScope.None)]
1110         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1111         static extern private bool nativeGetSafeCulture(Thread t, int appDomainId, bool isUI, ref CultureInfo safeCulture);
1112 #endif // FEATURE_LEAK_CULTURE_INFO
1113
1114         // As the culture can be customized object then we cannot hold any 
1115         // reference to it before we check if it is safe because the app domain 
1116         // owning this customized culture may get unloaded while executing this 
1117         // code. To achieve that we have to do the check using nativeGetSafeCulture 
1118         // as the thread cannot get interrupted during the FCALL. 
1119         // If the culture is safe (not customized or created in current app domain) 
1120         // then the FCALL will return a reference to that culture otherwise the 
1121         // FCALL will return failure. In case of failure we'll return the default culture.
1122         // If the app domain owning a customized culture that is set to teh thread and this
1123         // app domain get unloaded there is a code to clean up the culture from the thread
1124         // using the code in AppDomain::ReleaseDomainStores.
1125
1126         public CultureInfo CurrentUICulture {
1127             get {
1128                 Contract.Ensures(Contract.Result<CultureInfo>() != null);
1129 #if FEATURE_APPX
1130                 if(AppDomain.IsAppXModel()) {
1131                     return CultureInfo.GetCultureInfoForUserPreferredLanguageInAppX() ?? GetCurrentUICultureNoAppX();
1132                 } 
1133                 else 
1134 #endif
1135                 {
1136                     return GetCurrentUICultureNoAppX();
1137                 }
1138             }
1139
1140             [System.Security.SecuritySafeCritical]  // auto-generated
1141             [HostProtection(ExternalThreading=true)]
1142             set {
1143                 if (value == null) {
1144                     throw new ArgumentNullException("value");
1145                 }
1146                 Contract.EndContractBlock();
1147
1148                 //If they're trying to use a Culture with a name that we can't use in resource lookup,
1149                 //don't even let them set it on the thread.
1150                 CultureInfo.VerifyCultureName(value, true);
1151
1152                 // If you add more pre-conditions to this method, check to see if you also need to 
1153                 // add them to CultureInfo.DefaultThreadCurrentUICulture.set.
1154
1155 #if FEATURE_LEAK_CULTURE_INFO
1156                 if (nativeSetThreadUILocale(value.SortName) == false)
1157                 {
1158                     throw new ArgumentException(Environment.GetResourceString("Argument_InvalidResourceCultureName", value.Name));
1159                 }
1160                 value.StartCrossDomainTracking();
1161 #else
1162                 if (m_CurrentUICulture == null && m_CurrentCulture == null)
1163                     nativeInitCultureAccessors();
1164 #endif
1165
1166 #if FEATURE_LEGACYNETCF
1167                 if (CompatibilitySwitches.IsAppEarlierThanWindowsPhone8)
1168                 {
1169                     //
1170                     // NetCF had a 
1171
1172
1173
1174
1175
1176                     CultureInfo.SetCurrentUICultureQuirk(value);
1177                     return;
1178                 }
1179 #endif
1180                 if (!AppContextSwitches.NoAsyncCurrentCulture)
1181                 {
1182                     if (s_asyncLocalCurrentUICulture == null)
1183                     {
1184                         Interlocked.CompareExchange(ref s_asyncLocalCurrentUICulture, new AsyncLocal<CultureInfo>(AsyncLocalSetCurrentUICulture), null);
1185                     }
1186
1187                     // this one will set m_CurrentUICulture too
1188                     s_asyncLocalCurrentUICulture.Value = value;
1189                 }
1190                 else
1191                 {
1192                     m_CurrentUICulture = value;
1193                 }
1194             }
1195         }
1196
1197 #if FEATURE_LEAK_CULTURE_INFO
1198         [System.Security.SecuritySafeCritical]  // auto-generated
1199 #endif
1200         internal CultureInfo GetCurrentUICultureNoAppX() {
1201
1202             Contract.Ensures(Contract.Result<CultureInfo>() != null);
1203
1204             // Fetch a local copy of m_CurrentUICulture to 
1205             // avoid ----s that malicious user can introduce
1206             if (m_CurrentUICulture == null) {
1207                 CultureInfo appDomainDefaultUICulture = CultureInfo.DefaultThreadCurrentUICulture;
1208                 return (appDomainDefaultUICulture != null ? appDomainDefaultUICulture : CultureInfo.UserDefaultUICulture);
1209             }
1210
1211 #if FEATURE_LEAK_CULTURE_INFO
1212             CultureInfo culture = null;
1213
1214             if (!nativeGetSafeCulture(this, GetDomainID(), true, ref culture) || culture == null) {
1215                 return CultureInfo.UserDefaultUICulture;
1216             }
1217                 
1218             return culture;
1219 #else
1220             return m_CurrentUICulture;
1221 #endif
1222         }
1223
1224         // This returns the exposed context for a given context ID.
1225 #if FEATURE_LEAK_CULTURE_INFO
1226         [System.Security.SecurityCritical]  // auto-generated
1227         [ResourceExposure(ResourceScope.None)]
1228         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1229         static extern private bool nativeSetThreadUILocale(String locale);
1230 #endif
1231
1232         // As the culture can be customized object then we cannot hold any 
1233         // reference to it before we check if it is safe because the app domain 
1234         // owning this customized culture may get unloaded while executing this 
1235         // code. To achieve that we have to do the check using nativeGetSafeCulture 
1236         // as the thread cannot get interrupted during the FCALL. 
1237         // If the culture is safe (not customized or created in current app domain) 
1238         // then the FCALL will return a reference to that culture otherwise the 
1239         // FCALL will return failure. In case of failure we'll return the default culture.
1240         // If the app domain owning a customized culture that is set to teh thread and this
1241         // app domain get unloaded there is a code to clean up the culture from the thread
1242         // using the code in AppDomain::ReleaseDomainStores.
1243
1244         public CultureInfo CurrentCulture {
1245             get {
1246                 Contract.Ensures(Contract.Result<CultureInfo>() != null);
1247
1248 #if FEATURE_APPX
1249                 if(AppDomain.IsAppXModel()) {
1250                     return CultureInfo.GetCultureInfoForUserPreferredLanguageInAppX() ?? GetCurrentCultureNoAppX();
1251                 } 
1252                 else 
1253 #endif
1254                 {
1255                     return GetCurrentCultureNoAppX();
1256                 }
1257             }
1258
1259             [System.Security.SecuritySafeCritical]  // auto-generated
1260 #if FEATURE_LEAK_CULTURE_INFO
1261             [SecurityPermission(SecurityAction.Demand, ControlThread = true)]
1262 #endif
1263             set {
1264                 if (null==value) {
1265                     throw new ArgumentNullException("value");
1266                 }
1267                 Contract.EndContractBlock();
1268
1269                 // If you add more pre-conditions to this method, check to see if you also need to 
1270                 // add them to CultureInfo.DefaultThreadCurrentCulture.set.
1271
1272 #if FEATURE_LEAK_CULTURE_INFO
1273                 //If we can't set the nativeThreadLocale, we'll just let it stay
1274                 //at whatever value it had before.  This allows people who use
1275                 //just managed code not to be limited by the underlying OS.
1276                 CultureInfo.nativeSetThreadLocale(value.SortName);
1277                 value.StartCrossDomainTracking();
1278 #else
1279                 if (m_CurrentCulture == null && m_CurrentUICulture == null)
1280                     nativeInitCultureAccessors();
1281 #endif
1282
1283 #if FEATURE_LEGACYNETCF
1284                 if (CompatibilitySwitches.IsAppEarlierThanWindowsPhone8)
1285                 {
1286                     // See comment in CurrentUICulture setter
1287                     CultureInfo.SetCurrentCultureQuirk(value);
1288                     return;
1289                 }
1290 #endif
1291                 if (!AppContextSwitches.NoAsyncCurrentCulture)
1292                 {
1293                     if (s_asyncLocalCurrentCulture == null)
1294                     {
1295                         Interlocked.CompareExchange(ref s_asyncLocalCurrentCulture, new AsyncLocal<CultureInfo>(AsyncLocalSetCurrentCulture), null);
1296                     }
1297                     // this one will set m_CurrentCulture too
1298                     s_asyncLocalCurrentCulture.Value = value;
1299                 }
1300                 else
1301                 {
1302                     m_CurrentCulture = value;
1303                 }
1304             }
1305         }
1306
1307 #if FEATURE_LEAK_CULTURE_INFO
1308         [System.Security.SecuritySafeCritical]  // auto-generated
1309 #endif
1310         private CultureInfo GetCurrentCultureNoAppX() {
1311
1312             Contract.Ensures(Contract.Result<CultureInfo>() != null);
1313
1314             // Fetch a local copy of m_CurrentCulture to 
1315             // avoid ----s that malicious user can introduce
1316             if (m_CurrentCulture == null) {
1317                 CultureInfo appDomainDefaultCulture =  CultureInfo.DefaultThreadCurrentCulture;
1318                 return (appDomainDefaultCulture != null ? appDomainDefaultCulture : CultureInfo.UserDefaultCulture);
1319             }
1320
1321 #if FEATURE_LEAK_CULTURE_INFO
1322             CultureInfo culture = null;
1323               
1324             if (!nativeGetSafeCulture(this, GetDomainID(), false, ref culture) || culture == null) {
1325                 return CultureInfo.UserDefaultCulture;
1326             }
1327                 
1328             return culture;
1329 #else
1330             return m_CurrentCulture;
1331 #endif
1332
1333         }
1334
1335 #if! FEATURE_LEAK_CULTURE_INFO
1336         [System.Security.SecurityCritical]  // auto-generated
1337         [ResourceExposure(ResourceScope.None)]
1338         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
1339         [SuppressUnmanagedCodeSecurity]
1340         private static extern void nativeInitCultureAccessors();
1341 #endif
1342
1343         /*=============================================================*/
1344
1345         /*======================================================================
1346         **  Current thread context is stored in a slot in the thread local store
1347         **  CurrentContext gets the Context from the slot.
1348         ======================================================================*/
1349 #if FEATURE_REMOTING
1350         public static Context CurrentContext
1351         {
1352             [System.Security.SecurityCritical]  // auto-generated_required
1353             get
1354             {
1355                 return CurrentThread.GetCurrentContextInternal();
1356             }
1357         }
1358
1359         [System.Security.SecurityCritical]  // auto-generated
1360         internal Context GetCurrentContextInternal()
1361         {
1362             if (m_Context == null)
1363             {
1364                 m_Context = Context.DefaultContext;
1365             }
1366             return m_Context;
1367         }
1368 #endif        
1369
1370
1371 #if FEATURE_IMPERSONATION
1372         // Get and set thread's current principal (for role based security).
1373         public static IPrincipal CurrentPrincipal
1374         {
1375             [System.Security.SecuritySafeCritical]  // auto-generated
1376             get
1377             {
1378                 lock (CurrentThread)
1379                 {
1380                     IPrincipal principal = (IPrincipal)
1381                         CallContext.Principal;
1382                     if (principal == null)
1383                     {
1384                         principal = GetDomain().GetThreadPrincipal();
1385                         CallContext.Principal = principal;
1386                     }
1387                     return principal;
1388                 }
1389             }
1390
1391             [System.Security.SecuritySafeCritical]  // auto-generated
1392             [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.ControlPrincipal)]
1393             set
1394             {
1395                 CallContext.Principal = value;
1396             }
1397         }
1398
1399         // Private routine called from unmanaged code to set an initial
1400         // principal for a newly created thread.
1401         [System.Security.SecurityCritical]  // auto-generated
1402         private void SetPrincipalInternal(IPrincipal principal)
1403         {
1404             GetMutableExecutionContext().LogicalCallContext.SecurityData.Principal = principal;
1405         }
1406 #endif // FEATURE_IMPERSONATION
1407
1408 #if FEATURE_REMOTING   
1409
1410         // This returns the exposed context for a given context ID.
1411         [System.Security.SecurityCritical]  // auto-generated
1412         [ResourceExposure(ResourceScope.None)]
1413         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1414         internal static extern Context GetContextInternal(IntPtr id);
1415
1416         [System.Security.SecurityCritical]  // auto-generated
1417         [ResourceExposure(ResourceScope.None)]
1418         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1419         internal extern Object InternalCrossContextCallback(Context ctx, IntPtr ctxID, Int32 appDomainID, InternalCrossContextDelegate ftnToCall, Object[] args);
1420
1421         [System.Security.SecurityCritical]  // auto-generated
1422         internal Object InternalCrossContextCallback(Context ctx, InternalCrossContextDelegate ftnToCall, Object[] args)
1423         {
1424             return InternalCrossContextCallback(ctx, ctx.InternalContextID, 0, ftnToCall, args);
1425         }
1426
1427         // CompleteCrossContextCallback is called by the EE after transitioning to the requested context
1428         private static Object CompleteCrossContextCallback(InternalCrossContextDelegate ftnToCall, Object[] args)
1429         {
1430             return ftnToCall(args);
1431         }
1432 #endif // FEATURE_REMOTING
1433
1434         /*======================================================================
1435         ** Returns the current domain in which current thread is running.
1436         ======================================================================*/
1437
1438         [System.Security.SecurityCritical]  // auto-generated
1439         [ResourceExposure(ResourceScope.None)]
1440         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1441         private static extern AppDomain GetDomainInternal();
1442         [System.Security.SecurityCritical]  // auto-generated
1443         [ResourceExposure(ResourceScope.None)]
1444         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1445         private static extern AppDomain GetFastDomainInternal();
1446
1447         [System.Security.SecuritySafeCritical]  // auto-generated
1448         public static AppDomain GetDomain()
1449         {
1450             Contract.Ensures(Contract.Result<AppDomain>() != null);
1451
1452
1453             AppDomain ad;
1454             ad = GetFastDomainInternal();
1455             if (ad == null)
1456                 ad = GetDomainInternal();
1457
1458 #if FEATURE_REMOTING        
1459             Contract.Assert(CurrentThread.m_Context == null || CurrentThread.m_Context.AppDomain == ad, "AppDomains on the managed & unmanaged threads should match");
1460 #endif
1461             return ad;
1462         }
1463
1464
1465         /*
1466          *  This returns a unique id to identify an appdomain.
1467          */
1468         public static int GetDomainID()
1469         {
1470             return GetDomain().GetId();
1471         }
1472
1473
1474         // Retrieves the name of the thread.
1475         //
1476         public  String Name {
1477             get {
1478                 return m_Name;
1479
1480             }
1481             [System.Security.SecuritySafeCritical]  // auto-generated
1482             [HostProtection(ExternalThreading=true)]
1483             set {
1484                 lock(this) {
1485                     if (m_Name != null)
1486                         throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_WriteOnce"));
1487                     m_Name = value;
1488
1489                     InformThreadNameChange(GetNativeHandle(), value, (value != null) ? value.Length : 0);
1490                 }
1491             }
1492         }
1493
1494         [System.Security.SecurityCritical]  // auto-generated
1495         [ResourceExposure(ResourceScope.None)]
1496         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
1497         [SuppressUnmanagedCodeSecurity]
1498         private static extern void InformThreadNameChange(ThreadHandle t, String name, int len);
1499
1500         internal Object AbortReason {
1501             [System.Security.SecurityCritical]  // auto-generated
1502             get {
1503                 object result = null;
1504                 try
1505                 {
1506                     result = GetAbortReason();
1507                 }
1508                 catch (Exception e)
1509                 {
1510                     throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ExceptionStateCrossAppDomain"), e);
1511                 }
1512                 return result;
1513             }
1514             [System.Security.SecurityCritical]  // auto-generated
1515             set { SetAbortReason(value); }
1516         }
1517
1518         /*
1519          *  This marks the beginning of a critical code region.
1520          */
1521         [System.Security.SecuritySafeCritical]  // auto-generated
1522         [HostProtection(Synchronization=true, ExternalThreading=true)]
1523         [ResourceExposure(ResourceScope.None)]
1524         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1525         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
1526         public static extern void BeginCriticalRegion();
1527
1528         /*
1529          *  This marks the end of a critical code region.
1530          */
1531         [System.Security.SecuritySafeCritical]  // auto-generated
1532         [HostProtection(Synchronization=true, ExternalThreading=true)]
1533         [ResourceExposure(ResourceScope.None)]
1534         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1535         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
1536         public static extern void EndCriticalRegion();
1537
1538         /*
1539          *  This marks the beginning of a code region that requires thread affinity.
1540          */
1541         [System.Security.SecurityCritical]  // auto-generated_required
1542         [ResourceExposure(ResourceScope.None)]
1543         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1544         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
1545         public static extern void BeginThreadAffinity();
1546
1547         /*
1548          *  This marks the end of a code region that requires thread affinity.
1549          */
1550         [System.Security.SecurityCritical]  // auto-generated_required
1551         [ResourceExposure(ResourceScope.None)]
1552         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1553         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
1554         public static extern void EndThreadAffinity();
1555
1556         /*=========================================================================
1557         ** Volatile Read & Write and MemoryBarrier methods.
1558         ** Provides the ability to read and write values ensuring that the values
1559         ** are read/written each time they are accessed.
1560         =========================================================================*/
1561
1562         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1563         public static byte VolatileRead(ref byte address)
1564         {
1565             byte ret = address;
1566             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1567             return ret;
1568         }
1569
1570         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1571         public static short VolatileRead(ref short address)
1572         {
1573             short ret = address;
1574             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1575             return ret;
1576         }
1577
1578         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1579         public static int VolatileRead(ref int address)
1580         {
1581             int ret = address;
1582             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1583             return ret;
1584         }
1585
1586         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1587         public static long VolatileRead(ref long address)
1588         {
1589             long ret = address;
1590             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1591             return ret;
1592         }
1593
1594         [CLSCompliant(false)]
1595         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1596         public static sbyte VolatileRead(ref sbyte address)
1597         {
1598             sbyte ret = address;
1599             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1600             return ret;
1601         }
1602
1603         [CLSCompliant(false)]
1604         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1605         public static ushort VolatileRead(ref ushort address)
1606         {
1607             ushort ret = address;
1608             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1609             return ret;
1610         }
1611
1612         [CLSCompliant(false)]
1613         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1614         public static uint VolatileRead(ref uint address)
1615         {
1616             uint ret = address;
1617             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1618             return ret;
1619         }
1620
1621         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1622         public static IntPtr VolatileRead(ref IntPtr address)
1623         {
1624             IntPtr ret = address;
1625             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1626             return ret;
1627         }
1628
1629         [CLSCompliant(false)]
1630         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1631         public static UIntPtr VolatileRead(ref UIntPtr address)
1632         {
1633             UIntPtr ret = address;
1634             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1635             return ret;
1636         }
1637
1638         [CLSCompliant(false)]
1639         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1640         public static ulong VolatileRead(ref ulong address)
1641         {
1642             ulong ret = address;
1643             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1644             return ret;
1645         }
1646
1647         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1648         public static float VolatileRead(ref float address)
1649         {
1650             float ret = address;
1651             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1652             return ret;
1653         }
1654
1655         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1656         public static double VolatileRead(ref double address)
1657         {
1658             double ret = address;
1659             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1660             return ret;
1661         }
1662
1663         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1664         public static Object VolatileRead(ref Object address)
1665         {
1666             Object ret = address;
1667             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1668             return ret;
1669         }
1670
1671         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1672         public static void VolatileWrite(ref byte address, byte value)
1673         {
1674             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1675             address = value;
1676         }
1677
1678         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1679         public static void VolatileWrite(ref short address, short value)
1680         {
1681             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1682             address = value;
1683         }
1684
1685         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1686         public static void VolatileWrite(ref int address, int value)
1687         {
1688             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1689             address = value;
1690         }
1691
1692         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1693         public static void VolatileWrite(ref long address, long value)
1694         {
1695             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1696             address = value;
1697         }
1698
1699         [CLSCompliant(false)]
1700         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1701         public static void VolatileWrite(ref sbyte address, sbyte value)
1702         {
1703             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1704             address = value;
1705         }
1706
1707         [CLSCompliant(false)]
1708         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1709         public static void VolatileWrite(ref ushort address, ushort value)
1710         {
1711             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1712             address = value;
1713         }
1714
1715         [CLSCompliant(false)]
1716         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1717         public static void VolatileWrite(ref uint address, uint value)
1718         {
1719             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1720             address = value;
1721         }
1722
1723         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1724         public static void VolatileWrite(ref IntPtr address, IntPtr value)
1725         {
1726             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1727             address = value;
1728         }
1729
1730         [CLSCompliant(false)]
1731         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1732         public static void VolatileWrite(ref UIntPtr address, UIntPtr value)
1733         {
1734             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1735             address = value;
1736         }
1737
1738         [CLSCompliant(false)]
1739         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1740         public static void VolatileWrite(ref ulong address, ulong value)
1741         {
1742             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1743             address = value;
1744         }
1745
1746         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1747         public static void VolatileWrite(ref float address, float value)
1748         {
1749             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1750             address = value;
1751         }
1752
1753         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1754         public static void VolatileWrite(ref double address, double value)
1755         {
1756             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1757             address = value;
1758         }
1759
1760         [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
1761         public static void VolatileWrite(ref Object address, Object value)
1762         {
1763             MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
1764             address = value;
1765         }
1766 #endif
1767         [System.Security.SecuritySafeCritical]  // auto-generated
1768         [ResourceExposure(ResourceScope.None)]
1769         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1770         public static extern void MemoryBarrier();
1771
1772         private static LocalDataStoreMgr LocalDataStoreManager
1773         {
1774             get 
1775             {
1776                 if (s_LocalDataStoreMgr == null)
1777                 {
1778                     Interlocked.CompareExchange(ref s_LocalDataStoreMgr, new LocalDataStoreMgr(), null);    
1779                 }
1780
1781                 return s_LocalDataStoreMgr;
1782             }
1783         }
1784
1785 #if !FEATURE_CORECLR && !MOBILE
1786         void _Thread.GetTypeInfoCount(out uint pcTInfo)
1787         {
1788             throw new NotImplementedException();
1789         }
1790
1791         void _Thread.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
1792         {
1793             throw new NotImplementedException();
1794         }
1795
1796         void _Thread.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
1797         {
1798             throw new NotImplementedException();
1799         }
1800
1801         void _Thread.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
1802         {
1803             throw new NotImplementedException();
1804         }
1805 #endif
1806
1807 #if !MONO
1808         // Helper function to set the AbortReason for a thread abort.
1809         //  Checks that they're not alredy set, and then atomically updates
1810         //  the reason info (object + ADID).
1811         [System.Security.SecurityCritical]  // auto-generated
1812         [ResourceExposure(ResourceScope.None)]
1813         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1814         internal extern void SetAbortReason(Object o);
1815     
1816         // Helper function to retrieve the AbortReason from a thread
1817         //  abort.  Will perform cross-AppDomain marshalling if the object
1818         //  lives in a different AppDomain from the requester.
1819         [System.Security.SecurityCritical]  // auto-generated
1820         [ResourceExposure(ResourceScope.None)]
1821         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1822         internal extern Object GetAbortReason();
1823     
1824         // Helper function to clear the AbortReason.  Takes care of
1825         //  AppDomain related cleanup if required.
1826         [System.Security.SecurityCritical]  // auto-generated
1827         [ResourceExposure(ResourceScope.None)]
1828         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1829         internal extern void ClearAbortReason();
1830 #endif
1831
1832     } // End of class Thread
1833
1834     // declaring a local var of this enum type and passing it by ref into a function that needs to do a
1835     // stack crawl will both prevent inlining of the calle and pass an ESP point to stack crawl to
1836     // Declaring these in EH clauses is illegal; they must declared in the main method body
1837     [Serializable]
1838     internal enum StackCrawlMark
1839     {
1840         LookForMe = 0,
1841         LookForMyCaller = 1,
1842         LookForMyCallersCaller = 2,
1843         LookForThread = 3
1844     }
1845
1846 }