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