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