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