Thread.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733
  1. //
  2. // System.Threading.Thread.cs
  3. //
  4. // Author:
  5. // Dick Porter ([email protected])
  6. //
  7. // (C) Ximian, Inc. http://www.ximian.com
  8. // Copyright (C) 2004-2006 Novell, Inc (http://www.novell.com)
  9. //
  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:
  17. //
  18. // The above copyright notice and this permission notice shall be
  19. // included in all copies or substantial portions of the Software.
  20. //
  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.
  28. //
  29. using System.Runtime.Serialization;
  30. using System.Globalization;
  31. using System.Runtime.CompilerServices;
  32. using System.Runtime.InteropServices;
  33. using System.IO;
  34. using System.Collections.Generic;
  35. using System.Reflection;
  36. using System.Security;
  37. using System.Diagnostics;
  38. using System.Runtime.ConstrainedExecution;
  39. #if !NETCORE
  40. using System.Runtime.Serialization.Formatters.Binary;
  41. using System.Runtime.Remoting.Contexts;
  42. using System.Security.Principal;
  43. #endif
  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
  49. int lock_thread_id;
  50. // stores a thread handle
  51. IntPtr handle;
  52. IntPtr native_handle; // used only on Win32
  53. IntPtr unused3;
  54. /* accessed only from unmanaged code */
  55. private IntPtr name;
  56. private int name_len;
  57. private ThreadState state;
  58. private object abort_exc;
  59. private int abort_state_handle;
  60. /* thread_id is only accessed from unmanaged code */
  61. internal Int64 thread_id;
  62. private IntPtr debugger_thread; // FIXME switch to bool as soon as CI testing with corlib version bump works
  63. private UIntPtr static_data; /* GC-tracked */
  64. private IntPtr runtime_thread_info;
  65. /* current System.Runtime.Remoting.Contexts.Context instance
  66. keep as an object to avoid triggering its class constructor when not needed */
  67. private object current_appcontext;
  68. private object root_domain_thread;
  69. internal byte[] _serialized_principal;
  70. internal int _serialized_principal_version;
  71. private IntPtr appdomain_refs;
  72. private int interruption_requested;
  73. private IntPtr longlived;
  74. internal bool threadpool_thread;
  75. private bool thread_interrupt_requested;
  76. /* These are used from managed code */
  77. internal int stack_size;
  78. internal byte apartment_state;
  79. internal volatile int critical_region_level;
  80. internal int managed_id;
  81. private int small_id;
  82. private IntPtr manage_callback;
  83. private IntPtr unused4;
  84. private IntPtr flags;
  85. private IntPtr thread_pinning_ref;
  86. private IntPtr abort_protected_block_count;
  87. private int priority = (int) ThreadPriority.Normal;
  88. private IntPtr owned_mutex;
  89. private IntPtr suspended_event;
  90. private int self_suspended;
  91. /*
  92. * These fields are used to avoid having to increment corlib versions
  93. * when a new field is added to the unmanaged MonoThread structure.
  94. */
  95. private IntPtr unused1;
  96. private IntPtr unused2;
  97. /* This is used only to check that we are in sync between the representation
  98. * of MonoInternalThread in native and InternalThread in managed
  99. *
  100. * DO NOT RENAME! DO NOT ADD FIELDS AFTER! */
  101. private IntPtr last;
  102. #endregion
  103. #pragma warning restore 169, 414, 649
  104. // Closes the system thread handle
  105. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  106. private extern void Thread_free_internal();
  107. [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
  108. ~InternalThread() {
  109. Thread_free_internal();
  110. }
  111. }
  112. [StructLayout (LayoutKind.Sequential)]
  113. #if !NETCORE
  114. public
  115. #endif
  116. sealed partial class Thread {
  117. #pragma warning disable 414
  118. #region Sync with metadata/object-internals.h
  119. private InternalThread internal_thread;
  120. object m_ThreadStartArg;
  121. object pending_exception;
  122. #endregion
  123. #pragma warning restore 414
  124. // the name of current_thread is
  125. // important because they are used by the runtime.
  126. [ThreadStatic]
  127. static Thread current_thread;
  128. // can be both a ThreadStart and a ParameterizedThreadStart
  129. private MulticastDelegate m_Delegate;
  130. private ExecutionContext m_ExecutionContext; // this call context follows the logical thread
  131. private bool m_ExecutionContextBelongsToOuterScope;
  132. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  133. private extern void ConstructInternalThread ();
  134. private InternalThread Internal {
  135. get {
  136. if (internal_thread == null)
  137. ConstructInternalThread ();
  138. return internal_thread;
  139. }
  140. }
  141. /*
  142. * These two methods return an array in the target
  143. * domain with the same content as the argument. If
  144. * the argument is already in the target domain, then
  145. * the argument is returned, otherwise a copy.
  146. */
  147. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  148. private extern static byte[] ByteArrayToRootDomain (byte[] arr);
  149. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  150. private extern static byte[] ByteArrayToCurrentDomain (byte[] arr);
  151. #if !NETCORE
  152. IPrincipal principal;
  153. int principal_version;
  154. public static Context CurrentContext {
  155. get {
  156. return(AppDomain.InternalGetContext ());
  157. }
  158. }
  159. static void DeserializePrincipal (Thread th)
  160. {
  161. MemoryStream ms = new MemoryStream (ByteArrayToCurrentDomain (th.Internal._serialized_principal));
  162. int type = ms.ReadByte ();
  163. if (type == 0) {
  164. BinaryFormatter bf = new BinaryFormatter ();
  165. th.principal = (IPrincipal) bf.Deserialize (ms);
  166. th.principal_version = th.Internal._serialized_principal_version;
  167. } else if (type == 1) {
  168. BinaryReader reader = new BinaryReader (ms);
  169. string name = reader.ReadString ();
  170. string auth_type = reader.ReadString ();
  171. int n_roles = reader.ReadInt32 ();
  172. string [] roles = null;
  173. if (n_roles >= 0) {
  174. roles = new string [n_roles];
  175. for (int i = 0; i < n_roles; i++)
  176. roles [i] = reader.ReadString ();
  177. }
  178. th.principal = new GenericPrincipal (new GenericIdentity (name, auth_type), roles);
  179. } else if (type == 2 || type == 3) {
  180. string [] roles = type == 2 ? null : new string [0];
  181. th.principal = new GenericPrincipal (new GenericIdentity ("", ""), roles);
  182. }
  183. }
  184. static void SerializePrincipal (Thread th, IPrincipal value)
  185. {
  186. MemoryStream ms = new MemoryStream ();
  187. bool done = false;
  188. if (value.GetType () == typeof (GenericPrincipal)) {
  189. GenericPrincipal gp = (GenericPrincipal) value;
  190. if (gp.Identity != null && gp.Identity.GetType () == typeof (GenericIdentity)) {
  191. GenericIdentity id = (GenericIdentity) gp.Identity;
  192. if (id.Name == "" && id.AuthenticationType == "") {
  193. if (gp.Roles == null) {
  194. ms.WriteByte (2);
  195. done = true;
  196. } else if (gp.Roles.Length == 0) {
  197. ms.WriteByte (3);
  198. done = true;
  199. }
  200. } else {
  201. ms.WriteByte (1);
  202. BinaryWriter br = new BinaryWriter (ms);
  203. br.Write (gp.Identity.Name);
  204. br.Write (gp.Identity.AuthenticationType);
  205. string [] roles = gp.Roles;
  206. if (roles == null) {
  207. br.Write ((int) (-1));
  208. } else {
  209. br.Write (roles.Length);
  210. foreach (string s in roles) {
  211. br.Write (s);
  212. }
  213. }
  214. br.Flush ();
  215. done = true;
  216. }
  217. }
  218. }
  219. if (!done) {
  220. ms.WriteByte (0);
  221. BinaryFormatter bf = new BinaryFormatter ();
  222. try {
  223. bf.Serialize (ms, value);
  224. } catch {}
  225. }
  226. th.Internal._serialized_principal = ByteArrayToRootDomain (ms.ToArray ());
  227. }
  228. public static IPrincipal CurrentPrincipal {
  229. get {
  230. Thread th = CurrentThread;
  231. var logicalPrincipal = th.GetExecutionContextReader().LogicalCallContext.Principal;
  232. if (logicalPrincipal != null)
  233. return logicalPrincipal;
  234. if (th.principal_version != th.Internal._serialized_principal_version)
  235. th.principal = null;
  236. if (th.principal != null)
  237. return th.principal;
  238. if (th.Internal._serialized_principal != null) {
  239. try {
  240. DeserializePrincipal (th);
  241. return th.principal;
  242. } catch {}
  243. }
  244. th.principal = GetDomain ().DefaultPrincipal;
  245. th.principal_version = th.Internal._serialized_principal_version;
  246. return th.principal;
  247. }
  248. set {
  249. Thread th = CurrentThread;
  250. th.GetMutableExecutionContext().LogicalCallContext.Principal = value;
  251. if (value != GetDomain ().DefaultPrincipal) {
  252. ++th.Internal._serialized_principal_version;
  253. try {
  254. SerializePrincipal (th, value);
  255. } catch (Exception) {
  256. th.Internal._serialized_principal = null;
  257. }
  258. th.principal_version = th.Internal._serialized_principal_version;
  259. } else {
  260. th.Internal._serialized_principal = null;
  261. }
  262. th.principal = value;
  263. }
  264. }
  265. public static AppDomain GetDomain() {
  266. return AppDomain.CurrentDomain;
  267. }
  268. #endif
  269. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  270. private extern static Thread GetCurrentThread ();
  271. public static Thread CurrentThread {
  272. [ReliabilityContract (Consistency.WillNotCorruptState, Cer.MayFail)]
  273. get {
  274. Thread current = current_thread;
  275. if (current != null)
  276. return current;
  277. // This will set the current_thread tls variable
  278. return GetCurrentThread ();
  279. }
  280. }
  281. internal static int CurrentThreadId {
  282. get {
  283. return (int)(CurrentThread.internal_thread.thread_id);
  284. }
  285. }
  286. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  287. public extern static int GetDomainID();
  288. // Returns the system thread handle
  289. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  290. private extern bool Thread_internal (MulticastDelegate start);
  291. private Thread (InternalThread it) {
  292. internal_thread = it;
  293. }
  294. // part of ".NETPortable,Version=v4.0,Profile=Profile3" i.e. FX4 and SL4
  295. [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
  296. ~Thread ()
  297. {
  298. }
  299. [Obsolete ("Deprecated in favor of GetApartmentState, SetApartmentState and TrySetApartmentState.")]
  300. public ApartmentState ApartmentState {
  301. get {
  302. ValidateThreadState ();
  303. return (ApartmentState)Internal.apartment_state;
  304. }
  305. set {
  306. ValidateThreadState ();
  307. TrySetApartmentState (value);
  308. }
  309. }
  310. public bool IsThreadPoolThread {
  311. get {
  312. return IsThreadPoolThreadInternal;
  313. }
  314. }
  315. internal bool IsThreadPoolThreadInternal {
  316. get {
  317. return Internal.threadpool_thread;
  318. }
  319. set {
  320. Internal.threadpool_thread = value;
  321. }
  322. }
  323. public bool IsAlive {
  324. get {
  325. ThreadState curstate = GetState (Internal);
  326. if((curstate & ThreadState.Aborted) != 0 ||
  327. (curstate & ThreadState.Stopped) != 0 ||
  328. (curstate & ThreadState.Unstarted) != 0) {
  329. return(false);
  330. } else {
  331. return(true);
  332. }
  333. }
  334. }
  335. public bool IsBackground {
  336. get {
  337. var state = ValidateThreadState ();
  338. return (state & ThreadState.Background) != 0;
  339. }
  340. set {
  341. ValidateThreadState ();
  342. if (value) {
  343. SetState (Internal, ThreadState.Background);
  344. } else {
  345. ClrState (Internal, ThreadState.Background);
  346. }
  347. }
  348. }
  349. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  350. private extern static string GetName_internal (InternalThread thread);
  351. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  352. private extern static void SetName_internal (InternalThread thread, String name);
  353. /*
  354. * The thread name must be shared by appdomains, so it is stored in
  355. * unmanaged code.
  356. */
  357. public string Name {
  358. get {
  359. return GetName_internal (Internal);
  360. }
  361. set {
  362. SetName_internal (Internal, value);
  363. }
  364. }
  365. public ThreadState ThreadState {
  366. get {
  367. return GetState (Internal);
  368. }
  369. }
  370. #if MONO_FEATURE_THREAD_ABORT
  371. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  372. private extern static void Abort_internal (InternalThread thread, object stateInfo);
  373. public void Abort ()
  374. {
  375. Abort_internal (Internal, null);
  376. }
  377. public void Abort (object stateInfo)
  378. {
  379. Abort_internal (Internal, stateInfo);
  380. }
  381. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  382. extern object GetAbortExceptionState ();
  383. internal object AbortReason {
  384. get {
  385. return GetAbortExceptionState ();
  386. }
  387. }
  388. void ClearAbortReason ()
  389. {
  390. }
  391. #else
  392. [Obsolete ("Thread.Abort is not supported on the current platform.", true)]
  393. public void Abort ()
  394. {
  395. throw new PlatformNotSupportedException ("Thread.Abort is not supported on the current platform.");
  396. }
  397. [Obsolete ("Thread.Abort is not supported on the current platform.", true)]
  398. public void Abort (object stateInfo)
  399. {
  400. throw new PlatformNotSupportedException ("Thread.Abort is not supported on the current platform.");
  401. }
  402. [Obsolete ("Thread.ResetAbort is not supported on the current platform.", true)]
  403. public static void ResetAbort ()
  404. {
  405. throw new PlatformNotSupportedException ("Thread.ResetAbort is not supported on the current platform.");
  406. }
  407. internal object AbortReason {
  408. get {
  409. throw new PlatformNotSupportedException ("Thread.ResetAbort is not supported on the current platform.");
  410. }
  411. }
  412. #endif // MONO_FEATURE_THREAD_ABORT
  413. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  414. private extern static void SpinWait_nop ();
  415. [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
  416. public static void SpinWait (int iterations)
  417. {
  418. if (iterations < 0)
  419. return;
  420. while (iterations-- > 0)
  421. {
  422. SpinWait_nop ();
  423. }
  424. }
  425. void StartInternal (object principal, ref StackCrawlMark stackMark)
  426. {
  427. #if FEATURE_ROLE_BASED_SECURITY
  428. Internal._serialized_principal = CurrentThread.Internal._serialized_principal;
  429. #endif
  430. // Thread_internal creates and starts the new thread,
  431. if (!Thread_internal(m_Delegate))
  432. throw new SystemException ("Thread creation failed.");
  433. m_ThreadStartArg = null;
  434. }
  435. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  436. extern private static void SetState (InternalThread thread, ThreadState set);
  437. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  438. extern private static void ClrState (InternalThread thread, ThreadState clr);
  439. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  440. extern private static ThreadState GetState (InternalThread thread);
  441. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  442. extern public static byte VolatileRead (ref byte address);
  443. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  444. extern public static double VolatileRead (ref double address);
  445. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  446. extern public static short VolatileRead (ref short address);
  447. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  448. extern public static int VolatileRead (ref int address);
  449. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  450. extern public static long VolatileRead (ref long address);
  451. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  452. extern public static IntPtr VolatileRead (ref IntPtr address);
  453. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  454. extern public static object VolatileRead (ref object address);
  455. [CLSCompliant(false)]
  456. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  457. extern public static sbyte VolatileRead (ref sbyte address);
  458. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  459. extern public static float VolatileRead (ref float address);
  460. [CLSCompliant (false)]
  461. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  462. extern public static ushort VolatileRead (ref ushort address);
  463. [CLSCompliant (false)]
  464. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  465. extern public static uint VolatileRead (ref uint address);
  466. [CLSCompliant (false)]
  467. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  468. extern public static ulong VolatileRead (ref ulong address);
  469. [CLSCompliant (false)]
  470. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  471. extern public static UIntPtr VolatileRead (ref UIntPtr address);
  472. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  473. extern public static void VolatileWrite (ref byte address, byte value);
  474. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  475. extern public static void VolatileWrite (ref double address, double value);
  476. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  477. extern public static void VolatileWrite (ref short address, short value);
  478. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  479. extern public static void VolatileWrite (ref int address, int value);
  480. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  481. extern public static void VolatileWrite (ref long address, long value);
  482. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  483. extern public static void VolatileWrite (ref IntPtr address, IntPtr value);
  484. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  485. extern public static void VolatileWrite (ref object address, object value);
  486. [CLSCompliant(false)]
  487. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  488. extern public static void VolatileWrite (ref sbyte address, sbyte value);
  489. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  490. extern public static void VolatileWrite (ref float address, float value);
  491. [CLSCompliant (false)]
  492. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  493. extern public static void VolatileWrite (ref ushort address, ushort value);
  494. [CLSCompliant (false)]
  495. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  496. extern public static void VolatileWrite (ref uint address, uint value);
  497. [CLSCompliant (false)]
  498. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  499. extern public static void VolatileWrite (ref ulong address, ulong value);
  500. [CLSCompliant (false)]
  501. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  502. extern public static void VolatileWrite (ref UIntPtr address, UIntPtr value);
  503. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  504. extern static int SystemMaxStackStize ();
  505. static int GetProcessDefaultStackSize (int maxStackSize)
  506. {
  507. if (maxStackSize == 0)
  508. return 0;
  509. if (maxStackSize < 131072) // make sure stack is at least 128k big
  510. return 131072;
  511. int page_size = Environment.GetPageSize ();
  512. if ((maxStackSize % page_size) != 0) // round up to a divisible of page size
  513. maxStackSize = (maxStackSize / (page_size - 1)) * page_size;
  514. /* Respect the max stack size imposed by the system*/
  515. return Math.Min (maxStackSize, SystemMaxStackStize ());
  516. }
  517. void SetStart (MulticastDelegate start, int maxStackSize)
  518. {
  519. m_Delegate = start;
  520. Internal.stack_size = maxStackSize;
  521. }
  522. public int ManagedThreadId {
  523. [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
  524. get {
  525. return Internal.managed_id;
  526. }
  527. }
  528. [ReliabilityContract (Consistency.WillNotCorruptState, Cer.MayFail)]
  529. public static void BeginCriticalRegion ()
  530. {
  531. CurrentThread.Internal.critical_region_level++;
  532. }
  533. [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
  534. public static void EndCriticalRegion ()
  535. {
  536. CurrentThread.Internal.critical_region_level--;
  537. }
  538. [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
  539. public static void BeginThreadAffinity ()
  540. {
  541. // Managed and native threads are currently bound together.
  542. }
  543. [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
  544. public static void EndThreadAffinity ()
  545. {
  546. // Managed and native threads are currently bound together.
  547. }
  548. public ApartmentState GetApartmentState ()
  549. {
  550. ValidateThreadState ();
  551. return (ApartmentState)Internal.apartment_state;
  552. }
  553. public void SetApartmentState (ApartmentState state)
  554. {
  555. if (!TrySetApartmentState (state))
  556. throw new InvalidOperationException ("Failed to set the specified COM apartment state.");
  557. }
  558. public bool TrySetApartmentState (ApartmentState state)
  559. {
  560. if ((ThreadState & ThreadState.Unstarted) == 0)
  561. throw new ThreadStateException ("Thread was in an invalid state for the operation being executed.");
  562. if ((ApartmentState)Internal.apartment_state != ApartmentState.Unknown &&
  563. (ApartmentState)Internal.apartment_state != state)
  564. return false;
  565. Internal.apartment_state = (byte)state;
  566. return true;
  567. }
  568. [ComVisible (false)]
  569. public override int GetHashCode ()
  570. {
  571. return ManagedThreadId;
  572. }
  573. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  574. internal static extern void GetStackTraces (out Thread[] threads, out object[] stack_frames);
  575. // This is a mono extension to gather the stack traces for all running threads
  576. internal static Dictionary<Thread, StackTrace> Mono_GetStackTraces () {
  577. Thread[] threads;
  578. object[] stack_frames;
  579. GetStackTraces (out threads, out stack_frames);
  580. var res = new Dictionary<Thread, StackTrace> ();
  581. for (int i = 0; i < threads.Length; ++i)
  582. res [threads [i]] = new StackTrace ((StackFrame[])stack_frames [i]);
  583. return res;
  584. }
  585. #if !MONO_FEATURE_THREAD_SUSPEND_RESUME
  586. [Obsolete ("Thread.Suspend is not supported on the current platform.", true)]
  587. public void Suspend ()
  588. {
  589. throw new PlatformNotSupportedException ("Thread.Suspend is not supported on the current platform.");
  590. }
  591. [Obsolete ("Thread.Resume is not supported on the current platform.", true)]
  592. public void Resume ()
  593. {
  594. throw new PlatformNotSupportedException ("Thread.Resume is not supported on the current platform.");
  595. }
  596. #endif
  597. public void DisableComObjectEagerCleanup ()
  598. {
  599. throw new PlatformNotSupportedException ();
  600. }
  601. ThreadState ValidateThreadState ()
  602. {
  603. var state = GetState (Internal);
  604. if ((state & ThreadState.Stopped) != 0)
  605. throw new ThreadStateException ("Thread is dead; state can not be accessed.");
  606. return state;
  607. }
  608. public static int GetCurrentProcessorId() => global::Internal.Runtime.Augments.RuntimeThread.GetCurrentProcessorId();
  609. }
  610. }