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 jit_data;
71 private IntPtr runtime_thread_info;
72 /* current System.Runtime.Remoting.Contexts.Context instance
73 keep as an object to avoid triggering its class constructor when not needed */
74 private object current_appcontext;
75 private object pending_exception;
76 private object root_domain_thread;
77 internal byte[] _serialized_principal;
78 internal int _serialized_principal_version;
79 private IntPtr appdomain_refs;
80 private int interruption_requested;
81 private IntPtr suspend_event;
82 private IntPtr suspended_event;
83 private IntPtr resume_event;
84 private IntPtr synch_cs;
85 internal bool threadpool_thread;
86 private bool thread_dump_requested;
87 private bool thread_interrupt_requested;
88 private IntPtr end_stack;
89 /* These are used from managed code */
90 internal int stack_size;
91 internal byte apartment_state;
92 internal volatile int critical_region_level;
93 internal int managed_id;
95 private IntPtr manage_callback;
96 private IntPtr interrupt_on_stop;
98 private IntPtr android_tid;
99 private IntPtr thread_pinning_ref;
100 private int ignore_next_signal;
102 * These fields are used to avoid having to increment corlib versions
103 * when a new field is added to the unmanaged MonoThread structure.
105 private IntPtr unused0;
106 private IntPtr unused1;
107 private IntPtr unused2;
109 #pragma warning restore 169, 414, 649
111 // Closes the system thread handle
112 [MethodImplAttribute(MethodImplOptions.InternalCall)]
113 private extern void Thread_free_internal(IntPtr handle);
115 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
117 Thread_free_internal(system_thread_handle);
121 [ClassInterface (ClassInterfaceType.None)]
123 [ComDefaultInterface (typeof (_Thread))]
124 [StructLayout (LayoutKind.Sequential)]
126 public sealed class Thread : CriticalFinalizerObject {
128 public sealed class Thread : CriticalFinalizerObject, _Thread {
130 #pragma warning disable 414
131 #region Sync with metadata/object-internals.h
132 private InternalThread internal_thread;
134 private ExecutionContext ec_to_set;
136 #pragma warning restore 414
138 IPrincipal principal;
139 int principal_version;
140 bool current_culture_set;
141 bool current_ui_culture_set;
142 CultureInfo current_culture;
143 CultureInfo current_ui_culture;
145 // the name of local_slots, current_thread and _ec is
146 // important because they are used by the runtime.
148 static object[] local_slots;
151 static Thread current_thread;
153 /* The actual ExecutionContext of the thread. It's
154 ThreadStatic so that it's not shared between
157 static ExecutionContext _ec;
159 static NamedDataSlot namedDataSlot;
161 static internal CultureInfo default_culture;
162 static internal CultureInfo default_ui_culture;
164 // can be both a ThreadStart and a ParameterizedThreadStart
165 private MulticastDelegate threadstart;
166 //private string thread_name=null;
168 [MethodImplAttribute(MethodImplOptions.InternalCall)]
169 private extern void ConstructInternalThread ();
171 private InternalThread Internal {
173 if (internal_thread == null)
174 ConstructInternalThread ();
175 return internal_thread;
179 public static Context CurrentContext {
180 [SecurityPermission (SecurityAction.LinkDemand, Infrastructure=true)]
182 return(AppDomain.InternalGetContext ());
187 * These two methods return an array in the target
188 * domain with the same content as the argument. If
189 * the argument is already in the target domain, then
190 * the argument is returned, otherwise a copy.
192 [MethodImplAttribute(MethodImplOptions.InternalCall)]
193 private extern static byte[] ByteArrayToRootDomain (byte[] arr);
195 [MethodImplAttribute(MethodImplOptions.InternalCall)]
196 private extern static byte[] ByteArrayToCurrentDomain (byte[] arr);
198 static void DeserializePrincipal (Thread th)
200 MemoryStream ms = new MemoryStream (ByteArrayToCurrentDomain (th.Internal._serialized_principal));
201 int type = ms.ReadByte ();
203 BinaryFormatter bf = new BinaryFormatter ();
204 th.principal = (IPrincipal) bf.Deserialize (ms);
205 th.principal_version = th.Internal._serialized_principal_version;
206 } else if (type == 1) {
207 BinaryReader reader = new BinaryReader (ms);
208 string name = reader.ReadString ();
209 string auth_type = reader.ReadString ();
210 int n_roles = reader.ReadInt32 ();
211 string [] roles = null;
213 roles = new string [n_roles];
214 for (int i = 0; i < n_roles; i++)
215 roles [i] = reader.ReadString ();
217 th.principal = new GenericPrincipal (new GenericIdentity (name, auth_type), roles);
218 } else if (type == 2 || type == 3) {
219 string [] roles = type == 2 ? null : new string [0];
220 th.principal = new GenericPrincipal (new GenericIdentity ("", ""), roles);
224 static void SerializePrincipal (Thread th, IPrincipal value)
226 MemoryStream ms = new MemoryStream ();
228 if (value.GetType () == typeof (GenericPrincipal)) {
229 GenericPrincipal gp = (GenericPrincipal) value;
230 if (gp.Identity != null && gp.Identity.GetType () == typeof (GenericIdentity)) {
231 GenericIdentity id = (GenericIdentity) gp.Identity;
232 if (id.Name == "" && id.AuthenticationType == "") {
233 if (gp.Roles == null) {
236 } else if (gp.Roles.Length == 0) {
242 BinaryWriter br = new BinaryWriter (ms);
243 br.Write (gp.Identity.Name);
244 br.Write (gp.Identity.AuthenticationType);
245 string [] roles = gp.Roles;
247 br.Write ((int) (-1));
249 br.Write (roles.Length);
250 foreach (string s in roles) {
261 BinaryFormatter bf = new BinaryFormatter ();
263 bf.Serialize (ms, value);
266 th.Internal._serialized_principal = ByteArrayToRootDomain (ms.ToArray ());
269 public static IPrincipal CurrentPrincipal {
271 Thread th = CurrentThread;
273 if (th.principal_version != th.Internal._serialized_principal_version)
276 if (th.principal != null)
279 if (th.Internal._serialized_principal != null) {
281 DeserializePrincipal (th);
286 th.principal = GetDomain ().DefaultPrincipal;
287 th.principal_version = th.Internal._serialized_principal_version;
290 [SecurityPermission (SecurityAction.Demand, ControlPrincipal = true)]
292 Thread th = CurrentThread;
294 if (value != GetDomain ().DefaultPrincipal) {
295 ++th.Internal._serialized_principal_version;
297 SerializePrincipal (th, value);
298 } catch (Exception) {
299 th.Internal._serialized_principal = null;
301 th.principal_version = th.Internal._serialized_principal_version;
303 th.Internal._serialized_principal = null;
306 th.principal = value;
310 // Looks up the object associated with the current thread
311 // this is called by the JIT directly, too
312 [MethodImplAttribute(MethodImplOptions.InternalCall)]
313 private extern static InternalThread CurrentInternalThread_internal();
315 [MethodImplAttribute(MethodImplOptions.InternalCall)]
316 internal extern static uint AllocTlsData (Type type);
318 [MethodImplAttribute(MethodImplOptions.InternalCall)]
319 internal extern static void DestroyTlsData (uint offset);
321 public static Thread CurrentThread {
322 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.MayFail)]
324 if (current_thread == null)
325 current_thread = new Thread (CurrentInternalThread_internal ());
326 return current_thread;
330 internal static int CurrentThreadId {
332 return (int)(CurrentThread.internal_thread.thread_id);
336 static NamedDataSlot NamedDataSlot {
338 if (namedDataSlot == null)
339 Interlocked.CompareExchange (ref namedDataSlot, new NamedDataSlot (), null);
341 return namedDataSlot;
345 public static LocalDataStoreSlot AllocateNamedDataSlot (string name)
347 return NamedDataSlot.Allocate (name);
350 public static void FreeNamedDataSlot (string name)
352 NamedDataSlot.Free (name);
355 public static LocalDataStoreSlot AllocateDataSlot ()
357 return new LocalDataStoreSlot (true);
360 public static object GetData (LocalDataStoreSlot slot) {
361 object[] slots = local_slots;
363 throw new ArgumentNullException ("slot");
364 if (slots != null && slot.slot < slots.Length)
365 return slots [slot.slot];
369 public static void SetData (LocalDataStoreSlot slot, object data) {
370 object[] slots = local_slots;
372 throw new ArgumentNullException ("slot");
374 slots = new object [slot.slot + 2];
376 } else if (slot.slot >= slots.Length) {
377 object[] nslots = new object [slot.slot + 2];
378 slots.CopyTo (nslots, 0);
382 slots [slot.slot] = data;
385 [MethodImplAttribute (MethodImplOptions.InternalCall)]
386 internal extern static void FreeLocalSlotValues (int slot, bool thread_local);
388 public static LocalDataStoreSlot GetNamedDataSlot(string name)
390 return NamedDataSlot.Get (name);
393 public static AppDomain GetDomain() {
394 return AppDomain.CurrentDomain;
397 [MethodImplAttribute(MethodImplOptions.InternalCall)]
398 public extern static int GetDomainID();
400 [MethodImplAttribute(MethodImplOptions.InternalCall)]
401 private extern static void ResetAbort_internal();
403 [SecurityPermission (SecurityAction.Demand, ControlThread=true)]
404 public static void ResetAbort ()
406 ResetAbort_internal ();
409 [HostProtectionAttribute (SecurityAction.LinkDemand, Synchronization = true, ExternalThreading = true)]
410 [MethodImplAttribute(MethodImplOptions.InternalCall)]
411 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
412 public extern static bool Yield ();
415 [MethodImplAttribute(MethodImplOptions.InternalCall)]
416 private extern static void Sleep_internal(int ms);
418 public static void Sleep (int millisecondsTimeout)
420 if (millisecondsTimeout < Timeout.Infinite)
421 throw new ArgumentOutOfRangeException ("millisecondsTimeout", "Negative timeout");
423 Sleep_internal (millisecondsTimeout);
426 public static void Sleep (TimeSpan timeout)
428 long ms = (long) timeout.TotalMilliseconds;
429 if (ms < Timeout.Infinite || ms > Int32.MaxValue)
430 throw new ArgumentOutOfRangeException ("timeout", "timeout out of range");
432 Sleep_internal ((int) ms);
435 // Returns the system thread handle
436 [MethodImplAttribute(MethodImplOptions.InternalCall)]
437 private extern IntPtr Thread_internal (MulticastDelegate start);
439 public Thread(ThreadStart start) {
441 throw new ArgumentNullException("Null ThreadStart");
446 private Thread (InternalThread it) {
447 internal_thread = it;
450 // part of ".NETPortable,Version=v4.0,Profile=Profile3" i.e. FX4 and SL4
451 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
456 [Obsolete ("Deprecated in favor of GetApartmentState, SetApartmentState and TrySetApartmentState.")]
457 public ApartmentState ApartmentState {
459 if ((ThreadState & ThreadState.Stopped) != 0)
460 throw new ThreadStateException ("Thread is dead; state can not be accessed.");
462 return (ApartmentState)Internal.apartment_state;
466 TrySetApartmentState (value);
470 //[MethodImplAttribute (MethodImplOptions.InternalCall)]
471 //private static extern int current_lcid ();
473 public CultureInfo CurrentCulture {
475 CultureInfo culture = current_culture;
476 if (current_culture_set && culture != null)
479 if (default_culture != null)
480 return default_culture;
482 current_culture = culture = CultureInfo.ConstructCurrentCulture ();
486 [SecurityPermission (SecurityAction.Demand, ControlThread=true)]
489 throw new ArgumentNullException ("value");
491 value.CheckNeutral ();
492 current_culture = value;
493 current_culture_set = true;
497 public CultureInfo CurrentUICulture {
499 CultureInfo culture = current_ui_culture;
500 if (current_ui_culture_set && culture != null)
503 if (default_ui_culture != null)
504 return default_ui_culture;
506 current_ui_culture = culture = CultureInfo.ConstructCurrentUICulture ();
512 throw new ArgumentNullException ("value");
513 current_ui_culture = value;
514 current_ui_culture_set = true;
518 public bool IsThreadPoolThread {
520 return IsThreadPoolThreadInternal;
524 internal bool IsThreadPoolThreadInternal {
526 return Internal.threadpool_thread;
529 Internal.threadpool_thread = value;
533 public bool IsAlive {
535 ThreadState curstate = GetState (Internal);
537 if((curstate & ThreadState.Aborted) != 0 ||
538 (curstate & ThreadState.Stopped) != 0 ||
539 (curstate & ThreadState.Unstarted) != 0) {
547 public bool IsBackground {
549 ThreadState thread_state = GetState (Internal);
550 if ((thread_state & ThreadState.Stopped) != 0)
551 throw new ThreadStateException ("Thread is dead; state can not be accessed.");
553 return (thread_state & ThreadState.Background) != 0;
558 SetState (Internal, ThreadState.Background);
560 ClrState (Internal, ThreadState.Background);
565 [MethodImplAttribute(MethodImplOptions.InternalCall)]
566 private extern static string GetName_internal (InternalThread thread);
568 [MethodImplAttribute(MethodImplOptions.InternalCall)]
569 private extern static void SetName_internal (InternalThread thread, String name);
572 * The thread name must be shared by appdomains, so it is stored in
578 return GetName_internal (Internal);
582 SetName_internal (Internal, value);
586 public ThreadPriority Priority {
588 return (ThreadPriority)GetPriority (Internal);
592 // FIXME: This doesn't do anything yet
593 SetPriority (Internal, (int)value);
597 public ThreadState ThreadState {
599 return GetState (Internal);
603 [MethodImplAttribute(MethodImplOptions.InternalCall)]
604 private extern static void Abort_internal (InternalThread thread, object stateInfo);
606 [MethodImplAttribute(MethodImplOptions.InternalCall)]
607 private extern static int GetPriority (InternalThread thread);
609 [MethodImplAttribute(MethodImplOptions.InternalCall)]
610 private extern static void SetPriority (InternalThread thread, int priority);
612 [SecurityPermission (SecurityAction.Demand, ControlThread=true)]
615 Abort_internal (Internal, null);
618 [SecurityPermission (SecurityAction.Demand, ControlThread=true)]
619 public void Abort (object stateInfo)
621 Abort_internal (Internal, stateInfo);
624 [MethodImplAttribute(MethodImplOptions.InternalCall)]
625 internal extern object GetAbortExceptionState ();
627 [MethodImplAttribute (MethodImplOptions.InternalCall)]
628 private extern static void Interrupt_internal (InternalThread thread);
630 [SecurityPermission (SecurityAction.Demand, ControlThread=true)]
631 public void Interrupt ()
633 Interrupt_internal (Internal);
636 // The current thread joins with 'this'. Set ms to 0 to block
637 // until this actually exits.
638 [MethodImplAttribute(MethodImplOptions.InternalCall)]
639 private extern static bool Join_internal(InternalThread thread, int ms, IntPtr handle);
643 Join_internal(Internal, Timeout.Infinite, Internal.system_thread_handle);
646 public bool Join(int millisecondsTimeout)
648 if (millisecondsTimeout < Timeout.Infinite)
649 throw new ArgumentOutOfRangeException ("millisecondsTimeout", "Timeout less than zero");
651 return Join_internal (Internal, millisecondsTimeout, Internal.system_thread_handle);
654 public bool Join(TimeSpan timeout)
656 long ms = (long) timeout.TotalMilliseconds;
657 if (ms < Timeout.Infinite || ms > Int32.MaxValue)
658 throw new ArgumentOutOfRangeException ("timeout", "timeout out of range");
660 return Join_internal (Internal, (int) ms, Internal.system_thread_handle);
663 [MethodImplAttribute(MethodImplOptions.InternalCall)]
664 public extern static void MemoryBarrier ();
666 [MethodImplAttribute(MethodImplOptions.InternalCall)]
667 private extern void Resume_internal();
670 [SecurityPermission (SecurityAction.Demand, ControlThread=true)]
671 public void Resume ()
676 [MethodImplAttribute (MethodImplOptions.InternalCall)]
677 private extern static void SpinWait_nop ();
680 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
681 public static void SpinWait (int iterations)
685 while (iterations-- > 0)
691 private void StartInternal ()
693 current_thread = this;
695 if (threadstart is ThreadStart) {
696 ((ThreadStart) threadstart) ();
698 ((ParameterizedThreadStart) threadstart) (start_obj);
702 public void Start() {
703 // propagate informations from the original thread to the new thread
704 ec_to_set = ExecutionContext.Capture (false, true);
705 Internal._serialized_principal = CurrentThread.Internal._serialized_principal;
707 // Thread_internal creates and starts the new thread,
708 if (Thread_internal((ThreadStart) StartInternal) == (IntPtr) 0)
709 throw new SystemException ("Thread creation failed.");
712 [MethodImplAttribute(MethodImplOptions.InternalCall)]
713 private extern static void Suspend_internal(InternalThread thread);
716 [SecurityPermission (SecurityAction.Demand, ControlThread=true)]
717 public void Suspend ()
719 Suspend_internal (Internal);
722 [MethodImplAttribute (MethodImplOptions.InternalCall)]
723 extern private static void SetState (InternalThread thread, ThreadState set);
725 [MethodImplAttribute (MethodImplOptions.InternalCall)]
726 extern private static void ClrState (InternalThread thread, ThreadState clr);
728 [MethodImplAttribute (MethodImplOptions.InternalCall)]
729 extern private static ThreadState GetState (InternalThread thread);
731 [MethodImplAttribute (MethodImplOptions.InternalCall)]
732 extern public static byte VolatileRead (ref byte address);
734 [MethodImplAttribute (MethodImplOptions.InternalCall)]
735 extern public static double VolatileRead (ref double address);
737 [MethodImplAttribute (MethodImplOptions.InternalCall)]
738 extern public static short VolatileRead (ref short address);
740 [MethodImplAttribute (MethodImplOptions.InternalCall)]
741 extern public static int VolatileRead (ref int address);
743 [MethodImplAttribute (MethodImplOptions.InternalCall)]
744 extern public static long VolatileRead (ref long address);
746 [MethodImplAttribute (MethodImplOptions.InternalCall)]
747 extern public static IntPtr VolatileRead (ref IntPtr address);
749 [MethodImplAttribute (MethodImplOptions.InternalCall)]
750 extern public static object VolatileRead (ref object address);
752 [CLSCompliant(false)]
753 [MethodImplAttribute (MethodImplOptions.InternalCall)]
754 extern public static sbyte VolatileRead (ref sbyte address);
756 [MethodImplAttribute (MethodImplOptions.InternalCall)]
757 extern public static float VolatileRead (ref float address);
759 [CLSCompliant (false)]
760 [MethodImplAttribute (MethodImplOptions.InternalCall)]
761 extern public static ushort VolatileRead (ref ushort address);
763 [CLSCompliant (false)]
764 [MethodImplAttribute (MethodImplOptions.InternalCall)]
765 extern public static uint VolatileRead (ref uint address);
767 [CLSCompliant (false)]
768 [MethodImplAttribute (MethodImplOptions.InternalCall)]
769 extern public static ulong VolatileRead (ref ulong address);
771 [CLSCompliant (false)]
772 [MethodImplAttribute (MethodImplOptions.InternalCall)]
773 extern public static UIntPtr VolatileRead (ref UIntPtr address);
775 [MethodImplAttribute (MethodImplOptions.InternalCall)]
776 extern public static void VolatileWrite (ref byte address, byte value);
778 [MethodImplAttribute (MethodImplOptions.InternalCall)]
779 extern public static void VolatileWrite (ref double address, double value);
781 [MethodImplAttribute (MethodImplOptions.InternalCall)]
782 extern public static void VolatileWrite (ref short address, short value);
784 [MethodImplAttribute (MethodImplOptions.InternalCall)]
785 extern public static void VolatileWrite (ref int address, int value);
787 [MethodImplAttribute (MethodImplOptions.InternalCall)]
788 extern public static void VolatileWrite (ref long address, long value);
790 [MethodImplAttribute (MethodImplOptions.InternalCall)]
791 extern public static void VolatileWrite (ref IntPtr address, IntPtr value);
793 [MethodImplAttribute (MethodImplOptions.InternalCall)]
794 extern public static void VolatileWrite (ref object address, object value);
796 [CLSCompliant(false)]
797 [MethodImplAttribute (MethodImplOptions.InternalCall)]
798 extern public static void VolatileWrite (ref sbyte address, sbyte value);
800 [MethodImplAttribute (MethodImplOptions.InternalCall)]
801 extern public static void VolatileWrite (ref float address, float value);
803 [CLSCompliant (false)]
804 [MethodImplAttribute (MethodImplOptions.InternalCall)]
805 extern public static void VolatileWrite (ref ushort address, ushort value);
807 [CLSCompliant (false)]
808 [MethodImplAttribute (MethodImplOptions.InternalCall)]
809 extern public static void VolatileWrite (ref uint address, uint value);
811 [CLSCompliant (false)]
812 [MethodImplAttribute (MethodImplOptions.InternalCall)]
813 extern public static void VolatileWrite (ref ulong address, ulong value);
815 [CLSCompliant (false)]
816 [MethodImplAttribute (MethodImplOptions.InternalCall)]
817 extern public static void VolatileWrite (ref UIntPtr address, UIntPtr value);
819 [MethodImplAttribute (MethodImplOptions.InternalCall)]
820 extern static int SystemMaxStackStize ();
822 static int CheckStackSize (int maxStackSize)
824 if (maxStackSize < 0)
825 throw new ArgumentOutOfRangeException ("less than zero", "maxStackSize");
827 if (maxStackSize < 131072) // make sure stack is at least 128k big
830 int page_size = Environment.GetPageSize ();
832 if ((maxStackSize % page_size) != 0) // round up to a divisible of page size
833 maxStackSize = (maxStackSize / (page_size - 1)) * page_size;
835 /* Respect the max stack size imposed by the system*/
836 return Math.Min (maxStackSize, SystemMaxStackStize ());
839 public Thread (ThreadStart start, int maxStackSize)
842 throw new ArgumentNullException ("start");
845 Internal.stack_size = CheckStackSize (maxStackSize);;
848 public Thread (ParameterizedThreadStart start)
851 throw new ArgumentNullException ("start");
856 public Thread (ParameterizedThreadStart start, int maxStackSize)
859 throw new ArgumentNullException ("start");
862 Internal.stack_size = CheckStackSize (maxStackSize);
865 public ExecutionContext ExecutionContext {
866 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.MayFail)]
869 _ec = new ExecutionContext ();
877 internal bool HasExecutionContext {
883 internal void BranchExecutionContext (out ExecutionContext.Switcher switcher)
886 switcher = new ExecutionContext.Switcher ();
888 switcher = new ExecutionContext.Switcher (_ec);
889 _ec.CopyOnWrite = true;
893 internal void RestoreExecutionContext (ref ExecutionContext.Switcher switcher)
895 if (switcher.IsEmpty) {
900 switcher.Restore (_ec);
903 public int ManagedThreadId {
904 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
906 return Internal.managed_id;
910 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.MayFail)]
911 public static void BeginCriticalRegion ()
913 CurrentThread.Internal.critical_region_level++;
916 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
917 public static void EndCriticalRegion ()
919 CurrentThread.Internal.critical_region_level--;
922 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
923 public static void BeginThreadAffinity ()
925 // Managed and native threads are currently bound together.
928 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
929 public static void EndThreadAffinity ()
931 // Managed and native threads are currently bound together.
934 public ApartmentState GetApartmentState ()
936 return (ApartmentState)Internal.apartment_state;
939 public void SetApartmentState (ApartmentState state)
941 if (!TrySetApartmentState (state))
942 throw new InvalidOperationException ("Failed to set the specified COM apartment state.");
945 public bool TrySetApartmentState (ApartmentState state)
947 if ((ThreadState & ThreadState.Unstarted) == 0)
948 throw new ThreadStateException ("Thread was in an invalid state for the operation being executed.");
950 if ((ApartmentState)Internal.apartment_state != ApartmentState.Unknown &&
951 (ApartmentState)Internal.apartment_state != state)
954 Internal.apartment_state = (byte)state;
960 public override int GetHashCode ()
962 return ManagedThreadId;
965 public void Start (object parameter)
967 start_obj = parameter;
971 // NOTE: This method doesn't show in the class library status page because
972 // it cannot be "found" with the StrongNameIdentityPermission for ECMA key.
974 [SecurityPermission (SecurityAction.LinkDemand, UnmanagedCode = true)]
975 [StrongNameIdentityPermission (SecurityAction.LinkDemand, PublicKey="00000000000000000400000000000000")]
976 [Obsolete ("see CompressedStack class")]
977 public CompressedStack GetCompressedStack ()
980 throw new NotSupportedException ();
982 // Note: returns null if no CompressedStack has been set.
983 // However CompressedStack.GetCompressedStack returns an
984 // (empty?) CompressedStack instance.
985 CompressedStack cs = ExecutionContext.SecurityContext.CompressedStack;
986 return ((cs == null) || cs.IsEmpty ()) ? null : cs.CreateCopy ();
990 // NOTE: This method doesn't show in the class library status page because
991 // it cannot be "found" with the StrongNameIdentityPermission for ECMA key.
993 [SecurityPermission (SecurityAction.LinkDemand, UnmanagedCode = true)]
994 [StrongNameIdentityPermission (SecurityAction.LinkDemand, PublicKey="00000000000000000400000000000000")]
995 [Obsolete ("see CompressedStack class")]
996 public void SetCompressedStack (CompressedStack stack)
999 throw new NotSupportedException ();
1001 ExecutionContext.SecurityContext.CompressedStack = stack;
1006 void _Thread.GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
1008 throw new NotImplementedException ();
1011 void _Thread.GetTypeInfo (uint iTInfo, uint lcid, IntPtr ppTInfo)
1013 throw new NotImplementedException ();
1016 void _Thread.GetTypeInfoCount (out uint pcTInfo)
1018 throw new NotImplementedException ();
1021 void _Thread.Invoke (uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams,
1022 IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
1024 throw new NotImplementedException ();