2 // System.Threading.Thread.cs
5 // Dick Porter (dick@ximian.com)
7 // (C) Ximian, Inc. http://www.ximian.com
8 // Copyright (C) 2004-2006 Novell, Inc (http://www.novell.com)
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using System.Runtime.Remoting.Contexts;
31 using System.Runtime.Serialization;
32 using System.Runtime.Serialization.Formatters.Binary;
33 using System.Security.Permissions;
34 using System.Security.Principal;
35 using System.Globalization;
36 using System.Runtime.CompilerServices;
37 using System.Runtime.InteropServices;
39 using System.Collections.Generic;
40 using System.Reflection;
41 using System.Security;
42 using System.Runtime.ConstrainedExecution;
44 namespace System.Threading {
45 [StructLayout (LayoutKind.Sequential)]
46 sealed class InternalThread : CriticalFinalizerObject {
47 #pragma warning disable 169, 414, 649
48 #region Sync with metadata/object-internals.h
50 // stores a thread handle
51 internal IntPtr system_thread_handle;
53 /* Note this is an opaque object (an array), not a CultureInfo */
54 private object cached_culture_info;
55 /* accessed only from unmanaged code */
58 private ThreadState state;
59 private object abort_exc;
60 private int abort_state_handle;
61 /* thread_id is only accessed from unmanaged code */
62 internal Int64 thread_id;
64 /* start_notify is used by the runtime to signal that Start()
67 private IntPtr start_notify;
68 private IntPtr stack_ptr;
69 private UIntPtr static_data; /* GC-tracked */
70 private IntPtr runtime_thread_info;
71 /* current System.Runtime.Remoting.Contexts.Context instance
72 keep as an object to avoid triggering its class constructor when not needed */
73 private object current_appcontext;
74 private object pending_exception;
75 private object root_domain_thread;
76 internal byte[] _serialized_principal;
77 internal int _serialized_principal_version;
78 private IntPtr appdomain_refs;
79 private int interruption_requested;
80 private IntPtr synch_cs;
81 internal bool threadpool_thread;
82 private bool thread_interrupt_requested;
83 /* These are used from managed code */
84 internal int stack_size;
85 internal byte apartment_state;
86 internal volatile int critical_region_level;
87 internal int managed_id;
89 private IntPtr manage_callback;
90 private IntPtr interrupt_on_stop;
92 private IntPtr thread_pinning_ref;
93 private IntPtr async_invoke_method;
95 * These fields are used to avoid having to increment corlib versions
96 * when a new field is added to the unmanaged MonoThread structure.
98 private IntPtr unused1;
99 private IntPtr unused2;
101 #pragma warning restore 169, 414, 649
103 // Closes the system thread handle
104 [MethodImplAttribute(MethodImplOptions.InternalCall)]
105 private extern void Thread_free_internal(IntPtr handle);
107 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
109 Thread_free_internal(system_thread_handle);
113 [ClassInterface (ClassInterfaceType.None)]
115 [ComDefaultInterface (typeof (_Thread))]
116 [StructLayout (LayoutKind.Sequential)]
118 public sealed class Thread : CriticalFinalizerObject {
120 public sealed class Thread : CriticalFinalizerObject, _Thread {
122 #pragma warning disable 414
123 #region Sync with metadata/object-internals.h
124 private InternalThread internal_thread;
126 private ExecutionContext ec_to_set;
128 #pragma warning restore 414
130 IPrincipal principal;
131 int principal_version;
132 bool current_culture_set;
133 bool current_ui_culture_set;
134 CultureInfo current_culture;
135 CultureInfo current_ui_culture;
137 // the name of local_slots, current_thread and _ec is
138 // important because they are used by the runtime.
140 static object[] local_slots;
143 static Thread current_thread;
145 /* The actual ExecutionContext of the thread. It's
146 ThreadStatic so that it's not shared between
149 static ExecutionContext _ec;
151 static NamedDataSlot namedDataSlot;
153 static internal CultureInfo default_culture;
154 static internal CultureInfo default_ui_culture;
156 // can be both a ThreadStart and a ParameterizedThreadStart
157 private MulticastDelegate threadstart;
158 //private string thread_name=null;
160 [MethodImplAttribute(MethodImplOptions.InternalCall)]
161 private extern void ConstructInternalThread ();
163 private InternalThread Internal {
165 if (internal_thread == null)
166 ConstructInternalThread ();
167 return internal_thread;
171 public static Context CurrentContext {
172 [SecurityPermission (SecurityAction.LinkDemand, Infrastructure=true)]
174 return(AppDomain.InternalGetContext ());
179 * These two methods return an array in the target
180 * domain with the same content as the argument. If
181 * the argument is already in the target domain, then
182 * the argument is returned, otherwise a copy.
184 [MethodImplAttribute(MethodImplOptions.InternalCall)]
185 private extern static byte[] ByteArrayToRootDomain (byte[] arr);
187 [MethodImplAttribute(MethodImplOptions.InternalCall)]
188 private extern static byte[] ByteArrayToCurrentDomain (byte[] arr);
190 static void DeserializePrincipal (Thread th)
192 MemoryStream ms = new MemoryStream (ByteArrayToCurrentDomain (th.Internal._serialized_principal));
193 int type = ms.ReadByte ();
195 BinaryFormatter bf = new BinaryFormatter ();
196 th.principal = (IPrincipal) bf.Deserialize (ms);
197 th.principal_version = th.Internal._serialized_principal_version;
198 } else if (type == 1) {
199 BinaryReader reader = new BinaryReader (ms);
200 string name = reader.ReadString ();
201 string auth_type = reader.ReadString ();
202 int n_roles = reader.ReadInt32 ();
203 string [] roles = null;
205 roles = new string [n_roles];
206 for (int i = 0; i < n_roles; i++)
207 roles [i] = reader.ReadString ();
209 th.principal = new GenericPrincipal (new GenericIdentity (name, auth_type), roles);
210 } else if (type == 2 || type == 3) {
211 string [] roles = type == 2 ? null : new string [0];
212 th.principal = new GenericPrincipal (new GenericIdentity ("", ""), roles);
216 static void SerializePrincipal (Thread th, IPrincipal value)
218 MemoryStream ms = new MemoryStream ();
220 if (value.GetType () == typeof (GenericPrincipal)) {
221 GenericPrincipal gp = (GenericPrincipal) value;
222 if (gp.Identity != null && gp.Identity.GetType () == typeof (GenericIdentity)) {
223 GenericIdentity id = (GenericIdentity) gp.Identity;
224 if (id.Name == "" && id.AuthenticationType == "") {
225 if (gp.Roles == null) {
228 } else if (gp.Roles.Length == 0) {
234 BinaryWriter br = new BinaryWriter (ms);
235 br.Write (gp.Identity.Name);
236 br.Write (gp.Identity.AuthenticationType);
237 string [] roles = gp.Roles;
239 br.Write ((int) (-1));
241 br.Write (roles.Length);
242 foreach (string s in roles) {
253 BinaryFormatter bf = new BinaryFormatter ();
255 bf.Serialize (ms, value);
258 th.Internal._serialized_principal = ByteArrayToRootDomain (ms.ToArray ());
261 public static IPrincipal CurrentPrincipal {
263 Thread th = CurrentThread;
265 if (th.principal_version != th.Internal._serialized_principal_version)
268 if (th.principal != null)
271 if (th.Internal._serialized_principal != null) {
273 DeserializePrincipal (th);
278 th.principal = GetDomain ().DefaultPrincipal;
279 th.principal_version = th.Internal._serialized_principal_version;
282 [SecurityPermission (SecurityAction.Demand, ControlPrincipal = true)]
284 Thread th = CurrentThread;
286 if (value != GetDomain ().DefaultPrincipal) {
287 ++th.Internal._serialized_principal_version;
289 SerializePrincipal (th, value);
290 } catch (Exception) {
291 th.Internal._serialized_principal = null;
293 th.principal_version = th.Internal._serialized_principal_version;
295 th.Internal._serialized_principal = null;
298 th.principal = value;
302 // Looks up the object associated with the current thread
303 // this is called by the JIT directly, too
304 [MethodImplAttribute(MethodImplOptions.InternalCall)]
305 private extern static InternalThread CurrentInternalThread_internal();
307 [MethodImplAttribute(MethodImplOptions.InternalCall)]
308 internal extern static uint AllocTlsData (Type type);
310 [MethodImplAttribute(MethodImplOptions.InternalCall)]
311 internal extern static void DestroyTlsData (uint offset);
313 public static Thread CurrentThread {
314 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.MayFail)]
316 if (current_thread == null)
317 current_thread = new Thread (CurrentInternalThread_internal ());
318 return current_thread;
322 internal static int CurrentThreadId {
324 return (int)(CurrentThread.internal_thread.thread_id);
328 static NamedDataSlot NamedDataSlot {
330 if (namedDataSlot == null)
331 Interlocked.CompareExchange (ref namedDataSlot, new NamedDataSlot (true), null);
333 return namedDataSlot;
337 public static LocalDataStoreSlot AllocateNamedDataSlot (string name)
339 return NamedDataSlot.Allocate (name);
342 public static void FreeNamedDataSlot (string name)
344 NamedDataSlot.Free (name);
347 public static LocalDataStoreSlot AllocateDataSlot ()
349 return new LocalDataStoreSlot (true);
352 public static object GetData (LocalDataStoreSlot slot) {
353 object[] slots = local_slots;
355 throw new ArgumentNullException ("slot");
356 if (slots != null && slot.slot < slots.Length)
357 return slots [slot.slot];
361 public static void SetData (LocalDataStoreSlot slot, object data) {
362 object[] slots = local_slots;
364 throw new ArgumentNullException ("slot");
366 slots = new object [slot.slot + 2];
368 } else if (slot.slot >= slots.Length) {
369 object[] nslots = new object [slot.slot + 2];
370 slots.CopyTo (nslots, 0);
374 slots [slot.slot] = data;
377 [MethodImplAttribute (MethodImplOptions.InternalCall)]
378 internal extern static void FreeLocalSlotValues (int slot, bool thread_local);
380 public static LocalDataStoreSlot GetNamedDataSlot(string name)
382 return NamedDataSlot.Get (name);
385 public static AppDomain GetDomain() {
386 return AppDomain.CurrentDomain;
389 [MethodImplAttribute(MethodImplOptions.InternalCall)]
390 public extern static int GetDomainID();
392 [MethodImplAttribute(MethodImplOptions.InternalCall)]
393 private extern static void ResetAbort_internal();
395 [SecurityPermission (SecurityAction.Demand, ControlThread=true)]
396 public static void ResetAbort ()
398 ResetAbort_internal ();
401 [HostProtectionAttribute (SecurityAction.LinkDemand, Synchronization = true, ExternalThreading = true)]
402 [MethodImplAttribute(MethodImplOptions.InternalCall)]
403 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
404 public extern static bool Yield ();
407 [MethodImplAttribute(MethodImplOptions.InternalCall)]
408 private extern static void Sleep_internal(int ms);
410 public static void Sleep (int millisecondsTimeout)
412 if (millisecondsTimeout < Timeout.Infinite)
413 throw new ArgumentOutOfRangeException ("millisecondsTimeout", "Negative timeout");
415 Sleep_internal (millisecondsTimeout);
418 public static void Sleep (TimeSpan timeout)
420 long ms = (long) timeout.TotalMilliseconds;
421 if (ms < Timeout.Infinite || ms > Int32.MaxValue)
422 throw new ArgumentOutOfRangeException ("timeout", "timeout out of range");
424 Sleep_internal ((int) ms);
427 // Returns the system thread handle
428 [MethodImplAttribute(MethodImplOptions.InternalCall)]
429 private extern IntPtr Thread_internal (MulticastDelegate start);
431 public Thread(ThreadStart start) {
433 throw new ArgumentNullException("Null ThreadStart");
438 private Thread (InternalThread it) {
439 internal_thread = it;
442 // part of ".NETPortable,Version=v4.0,Profile=Profile3" i.e. FX4 and SL4
443 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
448 [Obsolete ("Deprecated in favor of GetApartmentState, SetApartmentState and TrySetApartmentState.")]
449 public ApartmentState ApartmentState {
451 if ((ThreadState & ThreadState.Stopped) != 0)
452 throw new ThreadStateException ("Thread is dead; state can not be accessed.");
454 return (ApartmentState)Internal.apartment_state;
458 TrySetApartmentState (value);
462 //[MethodImplAttribute (MethodImplOptions.InternalCall)]
463 //private static extern int current_lcid ();
465 public CultureInfo CurrentCulture {
467 CultureInfo culture = current_culture;
468 if (current_culture_set && culture != null)
471 if (default_culture != null)
472 return default_culture;
474 current_culture = culture = CultureInfo.ConstructCurrentCulture ();
478 [SecurityPermission (SecurityAction.Demand, ControlThread=true)]
481 throw new ArgumentNullException ("value");
483 value.CheckNeutral ();
484 current_culture = value;
485 current_culture_set = true;
489 public CultureInfo CurrentUICulture {
491 CultureInfo culture = current_ui_culture;
492 if (current_ui_culture_set && culture != null)
495 if (default_ui_culture != null)
496 return default_ui_culture;
498 current_ui_culture = culture = CultureInfo.ConstructCurrentUICulture ();
504 throw new ArgumentNullException ("value");
505 current_ui_culture = value;
506 current_ui_culture_set = true;
510 public bool IsThreadPoolThread {
512 return IsThreadPoolThreadInternal;
516 internal bool IsThreadPoolThreadInternal {
518 return Internal.threadpool_thread;
521 Internal.threadpool_thread = value;
525 public bool IsAlive {
527 ThreadState curstate = GetState (Internal);
529 if((curstate & ThreadState.Aborted) != 0 ||
530 (curstate & ThreadState.Stopped) != 0 ||
531 (curstate & ThreadState.Unstarted) != 0) {
539 public bool IsBackground {
541 ThreadState thread_state = GetState (Internal);
542 if ((thread_state & ThreadState.Stopped) != 0)
543 throw new ThreadStateException ("Thread is dead; state can not be accessed.");
545 return (thread_state & ThreadState.Background) != 0;
550 SetState (Internal, ThreadState.Background);
552 ClrState (Internal, ThreadState.Background);
557 [MethodImplAttribute(MethodImplOptions.InternalCall)]
558 private extern static string GetName_internal (InternalThread thread);
560 [MethodImplAttribute(MethodImplOptions.InternalCall)]
561 private extern static void SetName_internal (InternalThread thread, String name);
564 * The thread name must be shared by appdomains, so it is stored in
570 return GetName_internal (Internal);
574 SetName_internal (Internal, value);
578 public ThreadPriority Priority {
580 return (ThreadPriority)GetPriority (Internal);
584 // FIXME: This doesn't do anything yet
585 SetPriority (Internal, (int)value);
589 public ThreadState ThreadState {
591 return GetState (Internal);
595 [MethodImplAttribute(MethodImplOptions.InternalCall)]
596 private extern static void Abort_internal (InternalThread thread, object stateInfo);
598 [MethodImplAttribute(MethodImplOptions.InternalCall)]
599 private extern static int GetPriority (InternalThread thread);
601 [MethodImplAttribute(MethodImplOptions.InternalCall)]
602 private extern static void SetPriority (InternalThread thread, int priority);
604 [SecurityPermission (SecurityAction.Demand, ControlThread=true)]
607 Abort_internal (Internal, null);
610 [SecurityPermission (SecurityAction.Demand, ControlThread=true)]
611 public void Abort (object stateInfo)
613 Abort_internal (Internal, stateInfo);
616 [MethodImplAttribute(MethodImplOptions.InternalCall)]
617 extern object GetAbortExceptionState ();
619 internal object AbortReason {
621 return GetAbortExceptionState ();
625 [MethodImplAttribute (MethodImplOptions.InternalCall)]
626 private extern static void Interrupt_internal (InternalThread thread);
628 [SecurityPermission (SecurityAction.Demand, ControlThread=true)]
629 public void Interrupt ()
631 Interrupt_internal (Internal);
634 // The current thread joins with 'this'. Set ms to 0 to block
635 // until this actually exits.
636 [MethodImplAttribute(MethodImplOptions.InternalCall)]
637 private extern static bool Join_internal(InternalThread thread, int ms, IntPtr handle);
641 Join_internal(Internal, Timeout.Infinite, Internal.system_thread_handle);
644 public bool Join(int millisecondsTimeout)
646 if (millisecondsTimeout < Timeout.Infinite)
647 throw new ArgumentOutOfRangeException ("millisecondsTimeout", "Timeout less than zero");
649 return Join_internal (Internal, millisecondsTimeout, Internal.system_thread_handle);
652 public bool Join(TimeSpan timeout)
654 long ms = (long) timeout.TotalMilliseconds;
655 if (ms < Timeout.Infinite || ms > Int32.MaxValue)
656 throw new ArgumentOutOfRangeException ("timeout", "timeout out of range");
658 return Join_internal (Internal, (int) ms, Internal.system_thread_handle);
661 [MethodImplAttribute(MethodImplOptions.InternalCall)]
662 public extern static void MemoryBarrier ();
664 [MethodImplAttribute(MethodImplOptions.InternalCall)]
665 private extern void Resume_internal();
668 [SecurityPermission (SecurityAction.Demand, ControlThread=true)]
669 public void Resume ()
674 [MethodImplAttribute (MethodImplOptions.InternalCall)]
675 private extern static void SpinWait_nop ();
678 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
679 public static void SpinWait (int iterations)
683 while (iterations-- > 0)
689 private void StartInternal ()
691 current_thread = this;
693 if (threadstart is ThreadStart) {
694 ((ThreadStart) threadstart) ();
696 ((ParameterizedThreadStart) threadstart) (start_obj);
700 public void Start() {
701 // propagate informations from the original thread to the new thread
702 ec_to_set = ExecutionContext.Capture (false, true);
703 Internal._serialized_principal = CurrentThread.Internal._serialized_principal;
705 // Thread_internal creates and starts the new thread,
706 if (Thread_internal((ThreadStart) StartInternal) == (IntPtr) 0)
707 throw new SystemException ("Thread creation failed.");
710 [MethodImplAttribute(MethodImplOptions.InternalCall)]
711 private extern static void Suspend_internal(InternalThread thread);
714 [SecurityPermission (SecurityAction.Demand, ControlThread=true)]
715 public void Suspend ()
717 Suspend_internal (Internal);
720 [MethodImplAttribute (MethodImplOptions.InternalCall)]
721 extern private static void SetState (InternalThread thread, ThreadState set);
723 [MethodImplAttribute (MethodImplOptions.InternalCall)]
724 extern private static void ClrState (InternalThread thread, ThreadState clr);
726 [MethodImplAttribute (MethodImplOptions.InternalCall)]
727 extern private static ThreadState GetState (InternalThread thread);
729 [MethodImplAttribute (MethodImplOptions.InternalCall)]
730 extern public static byte VolatileRead (ref byte address);
732 [MethodImplAttribute (MethodImplOptions.InternalCall)]
733 extern public static double VolatileRead (ref double address);
735 [MethodImplAttribute (MethodImplOptions.InternalCall)]
736 extern public static short VolatileRead (ref short address);
738 [MethodImplAttribute (MethodImplOptions.InternalCall)]
739 extern public static int VolatileRead (ref int address);
741 [MethodImplAttribute (MethodImplOptions.InternalCall)]
742 extern public static long VolatileRead (ref long address);
744 [MethodImplAttribute (MethodImplOptions.InternalCall)]
745 extern public static IntPtr VolatileRead (ref IntPtr address);
747 [MethodImplAttribute (MethodImplOptions.InternalCall)]
748 extern public static object VolatileRead (ref object address);
750 [CLSCompliant(false)]
751 [MethodImplAttribute (MethodImplOptions.InternalCall)]
752 extern public static sbyte VolatileRead (ref sbyte address);
754 [MethodImplAttribute (MethodImplOptions.InternalCall)]
755 extern public static float VolatileRead (ref float address);
757 [CLSCompliant (false)]
758 [MethodImplAttribute (MethodImplOptions.InternalCall)]
759 extern public static ushort VolatileRead (ref ushort address);
761 [CLSCompliant (false)]
762 [MethodImplAttribute (MethodImplOptions.InternalCall)]
763 extern public static uint VolatileRead (ref uint address);
765 [CLSCompliant (false)]
766 [MethodImplAttribute (MethodImplOptions.InternalCall)]
767 extern public static ulong VolatileRead (ref ulong address);
769 [CLSCompliant (false)]
770 [MethodImplAttribute (MethodImplOptions.InternalCall)]
771 extern public static UIntPtr VolatileRead (ref UIntPtr address);
773 [MethodImplAttribute (MethodImplOptions.InternalCall)]
774 extern public static void VolatileWrite (ref byte address, byte value);
776 [MethodImplAttribute (MethodImplOptions.InternalCall)]
777 extern public static void VolatileWrite (ref double address, double value);
779 [MethodImplAttribute (MethodImplOptions.InternalCall)]
780 extern public static void VolatileWrite (ref short address, short value);
782 [MethodImplAttribute (MethodImplOptions.InternalCall)]
783 extern public static void VolatileWrite (ref int address, int value);
785 [MethodImplAttribute (MethodImplOptions.InternalCall)]
786 extern public static void VolatileWrite (ref long address, long value);
788 [MethodImplAttribute (MethodImplOptions.InternalCall)]
789 extern public static void VolatileWrite (ref IntPtr address, IntPtr value);
791 [MethodImplAttribute (MethodImplOptions.InternalCall)]
792 extern public static void VolatileWrite (ref object address, object value);
794 [CLSCompliant(false)]
795 [MethodImplAttribute (MethodImplOptions.InternalCall)]
796 extern public static void VolatileWrite (ref sbyte address, sbyte value);
798 [MethodImplAttribute (MethodImplOptions.InternalCall)]
799 extern public static void VolatileWrite (ref float address, float value);
801 [CLSCompliant (false)]
802 [MethodImplAttribute (MethodImplOptions.InternalCall)]
803 extern public static void VolatileWrite (ref ushort address, ushort value);
805 [CLSCompliant (false)]
806 [MethodImplAttribute (MethodImplOptions.InternalCall)]
807 extern public static void VolatileWrite (ref uint address, uint value);
809 [CLSCompliant (false)]
810 [MethodImplAttribute (MethodImplOptions.InternalCall)]
811 extern public static void VolatileWrite (ref ulong address, ulong value);
813 [CLSCompliant (false)]
814 [MethodImplAttribute (MethodImplOptions.InternalCall)]
815 extern public static void VolatileWrite (ref UIntPtr address, UIntPtr value);
817 [MethodImplAttribute (MethodImplOptions.InternalCall)]
818 extern static int SystemMaxStackStize ();
820 static int CheckStackSize (int maxStackSize)
822 if (maxStackSize < 0)
823 throw new ArgumentOutOfRangeException ("less than zero", "maxStackSize");
825 if (maxStackSize < 131072) // make sure stack is at least 128k big
828 int page_size = Environment.GetPageSize ();
830 if ((maxStackSize % page_size) != 0) // round up to a divisible of page size
831 maxStackSize = (maxStackSize / (page_size - 1)) * page_size;
833 /* Respect the max stack size imposed by the system*/
834 return Math.Min (maxStackSize, SystemMaxStackStize ());
837 public Thread (ThreadStart start, int maxStackSize)
840 throw new ArgumentNullException ("start");
843 Internal.stack_size = CheckStackSize (maxStackSize);;
846 public Thread (ParameterizedThreadStart start)
849 throw new ArgumentNullException ("start");
854 public Thread (ParameterizedThreadStart start, int maxStackSize)
857 throw new ArgumentNullException ("start");
860 Internal.stack_size = CheckStackSize (maxStackSize);
863 public ExecutionContext ExecutionContext {
864 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.MayFail)]
867 _ec = new ExecutionContext ();
875 internal bool HasExecutionContext {
881 internal void BranchExecutionContext (out ExecutionContext.Switcher switcher)
884 switcher = new ExecutionContext.Switcher ();
886 switcher = new ExecutionContext.Switcher (_ec);
887 _ec.CopyOnWrite = true;
891 internal void RestoreExecutionContext (ref ExecutionContext.Switcher switcher)
893 if (switcher.IsEmpty) {
898 switcher.Restore (_ec);
901 public int ManagedThreadId {
902 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
904 return Internal.managed_id;
908 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.MayFail)]
909 public static void BeginCriticalRegion ()
911 CurrentThread.Internal.critical_region_level++;
914 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
915 public static void EndCriticalRegion ()
917 CurrentThread.Internal.critical_region_level--;
920 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
921 public static void BeginThreadAffinity ()
923 // Managed and native threads are currently bound together.
926 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
927 public static void EndThreadAffinity ()
929 // Managed and native threads are currently bound together.
932 public ApartmentState GetApartmentState ()
934 return (ApartmentState)Internal.apartment_state;
937 public void SetApartmentState (ApartmentState state)
939 if (!TrySetApartmentState (state))
940 throw new InvalidOperationException ("Failed to set the specified COM apartment state.");
943 public bool TrySetApartmentState (ApartmentState state)
945 if ((ThreadState & ThreadState.Unstarted) == 0)
946 throw new ThreadStateException ("Thread was in an invalid state for the operation being executed.");
948 if ((ApartmentState)Internal.apartment_state != ApartmentState.Unknown &&
949 (ApartmentState)Internal.apartment_state != state)
952 Internal.apartment_state = (byte)state;
958 public override int GetHashCode ()
960 return ManagedThreadId;
963 public void Start (object parameter)
965 start_obj = parameter;
969 // NOTE: This method doesn't show in the class library status page because
970 // it cannot be "found" with the StrongNameIdentityPermission for ECMA key.
972 [SecurityPermission (SecurityAction.LinkDemand, UnmanagedCode = true)]
973 [StrongNameIdentityPermission (SecurityAction.LinkDemand, PublicKey="00000000000000000400000000000000")]
974 [Obsolete ("see CompressedStack class")]
975 public CompressedStack GetCompressedStack ()
978 throw new NotSupportedException ();
980 // Note: returns null if no CompressedStack has been set.
981 // However CompressedStack.GetCompressedStack returns an
982 // (empty?) CompressedStack instance.
983 CompressedStack cs = ExecutionContext.SecurityContext.CompressedStack;
984 return ((cs == null) || cs.IsEmpty ()) ? null : cs.CreateCopy ();
988 // NOTE: This method doesn't show in the class library status page because
989 // it cannot be "found" with the StrongNameIdentityPermission for ECMA key.
991 [SecurityPermission (SecurityAction.LinkDemand, UnmanagedCode = true)]
992 [StrongNameIdentityPermission (SecurityAction.LinkDemand, PublicKey="00000000000000000400000000000000")]
993 [Obsolete ("see CompressedStack class")]
994 public void SetCompressedStack (CompressedStack stack)
997 throw new NotSupportedException ();
999 ExecutionContext.SecurityContext.CompressedStack = stack;
1004 void _Thread.GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
1006 throw new NotImplementedException ();
1009 void _Thread.GetTypeInfo (uint iTInfo, uint lcid, IntPtr ppTInfo)
1011 throw new NotImplementedException ();
1014 void _Thread.GetTypeInfoCount (out uint pcTInfo)
1016 throw new NotImplementedException ();
1019 void _Thread.Invoke (uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams,
1020 IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
1022 throw new NotImplementedException ();
1026 internal CultureInfo GetCurrentUICultureNoAppX ()
1028 return CultureInfo.CurrentUICulture;