ae5bdbfd586d3391d656861047590897068957ca
[mono.git] / mcs / class / corlib / Test / System.Threading / ThreadTest.cs
1 // ThreadTest.cs - NUnit Test Cases for the System.Threading.Thread class
2 //
3 // Authors
4 //      Eduardo Garcia Cebollero (kiwnix@yahoo.es)
5 //      Sebastien Pouliot  <sebastien@ximian.com>
6 //
7 // (C) Eduardo Garcia Cebollero.
8 // (C) Ximian, Inc.  http://www.ximian.com
9 // (C) 2004 Novell (http://www.novell.com)
10 //
11
12 using System;
13 using System.Globalization;
14 using System.Security.Principal;
15 using System.Threading;
16 using System.Threading.Tasks;
17 using System.Reflection;
18 using System.Collections.Generic;
19 using SD = System.Diagnostics;
20
21 using NUnit.Framework;
22
23 namespace MonoTests.System.Threading
24 {
25         // These tests seem to hang the 2.0 framework. So they are disabled for now
26         // Don't reenable them until you can run a few thousand times on an SMP box.
27         [Category ("NotWorking")]
28         public class ThreadedPrincipalTest
29         {
30                 public static void NoPrincipal () 
31                 {
32                         AppDomain.CurrentDomain.SetPrincipalPolicy (PrincipalPolicy.NoPrincipal);
33                         IPrincipal p = Thread.CurrentPrincipal;
34                         Assert.IsNull (p, "#1");
35
36                         Thread.CurrentPrincipal = new GenericPrincipal (new GenericIdentity ("mono"), null);
37                         Assert.IsNotNull (Thread.CurrentPrincipal, "#2");
38
39                         Thread.CurrentPrincipal = null;
40                         Assert.IsNull (Thread.CurrentPrincipal, "#3");
41                         // in this case we can return to null
42                 }
43
44                 public static void UnauthenticatedPrincipal () 
45                 {
46                         AppDomain.CurrentDomain.SetPrincipalPolicy (PrincipalPolicy.UnauthenticatedPrincipal);
47                         IPrincipal p = Thread.CurrentPrincipal;
48                         Assert.IsNotNull (p, "#1");
49                         Assert.IsTrue ((p is GenericPrincipal), "#2");
50                         Assert.AreEqual (String.Empty, p.Identity.Name, "#3");
51                         Assert.AreEqual (String.Empty, p.Identity.AuthenticationType, "#4");
52                         Assert.IsFalse (p.Identity.IsAuthenticated, "#5");
53
54                         Thread.CurrentPrincipal = new GenericPrincipal (new GenericIdentity ("mono"), null);
55                         Assert.IsNotNull (Thread.CurrentPrincipal, "#6");
56
57                         Thread.CurrentPrincipal = null;
58                         Assert.IsNotNull (Thread.CurrentPrincipal, "#7");
59                         // in this case we can't return to null
60                 }
61
62                 public static void WindowsPrincipal () 
63                 {
64                         AppDomain.CurrentDomain.SetPrincipalPolicy (PrincipalPolicy.WindowsPrincipal);
65                         IPrincipal p = Thread.CurrentPrincipal;
66                         Assert.IsNotNull (p, "#1");
67                         Assert.IsTrue ((p is WindowsPrincipal), "#2");
68                         Assert.IsNotNull (p.Identity.Name, "#3");
69                         Assert.IsNotNull (p.Identity.AuthenticationType, "#4");
70                         Assert.IsTrue (p.Identity.IsAuthenticated, "#5");
71
72                         // note: we can switch from a WindowsPrincipal to a GenericPrincipal
73                         Thread.CurrentPrincipal = new GenericPrincipal (new GenericIdentity ("mono"), null);
74                         Assert.IsNotNull (Thread.CurrentPrincipal, "#6");
75
76                         Thread.CurrentPrincipal = null;
77                         Assert.IsNotNull (Thread.CurrentPrincipal, "#7");
78                         // in this case we can't return to null
79                 }
80
81                 public static void CopyOnNewThread ()
82                 {
83                         Assert.IsNotNull (Thread.CurrentPrincipal, "#1");
84                         Assert.AreEqual ("good", Thread.CurrentPrincipal.Identity.Name, "#2");
85                 }
86         }
87
88         [TestFixture]
89         [Category("MobileNotWorking")] // Abort #10240
90         public class ThreadTest
91         {
92                 //TimeSpan Infinite = new TimeSpan (-10000);    // -10000 ticks == -1 ms
93                 TimeSpan SmallNegative = new TimeSpan (-2);     // between 0 and -1.0 (infinite) ms
94                 TimeSpan Negative = new TimeSpan (-20000);      // really negative
95                 //TimeSpan MaxValue = TimeSpan.FromMilliseconds ((long) Int32.MaxValue);
96                 TimeSpan TooLarge = TimeSpan.FromMilliseconds ((long) Int32.MaxValue + 1);
97
98                 //Some Classes to test as threads
99                 private class C1Test
100                 {
101                         public int cnt;
102                         public Thread thread1;
103                         public bool endm1;
104                         public bool endm2;
105
106                         public C1Test()
107                         {
108                                 thread1 = (Thread)null;
109                                 this.cnt = 0;
110                                 endm1 = endm2 = false;
111                         }
112                         
113                         public void TestMethod()
114                         {
115                                 while (cnt < 10)
116                                 {
117                                         cnt++;
118                                 }
119                                 endm1 = true;
120                         }
121                         public void TestMethod2()
122                         {
123                                 if (!(thread1==(Thread)null) )
124                                 {
125                                         thread1.Join();
126                                 }
127                                 endm2 = true;
128                         }
129                 }
130
131                 private class C2Test
132                 {
133                         public int cnt;
134                         public bool run = false;
135                         
136                         public C2Test()
137                         {
138                                 this.cnt = 0;
139                         }
140
141                         public void TestMethod()
142                         {
143                                 run = true;
144                                 while (true)
145                                 {
146                                         if (cnt < 1000)
147                                                 cnt++;
148                                         else
149                                                 cnt = 0;
150                                 }
151                         }
152                 }
153                 
154                 private class C3Test
155                 {
156                         public C1Test sub_class;
157                         public Thread sub_thread;
158
159                         public C3Test()
160                         {
161                                 sub_class = new C1Test();
162                                 sub_thread = new Thread(new ThreadStart(sub_class.TestMethod));
163                         }
164
165                         public void TestMethod1()
166                         {
167                                 sub_thread.Start();
168                                 Thread.Sleep (100);
169 #if MONO_FEATURE_THREAD_ABORT
170                                 sub_thread.Abort();
171 #else
172                                 sub_thread.Interrupt ();
173 #endif
174                         }
175                 }
176                 
177                 private class C4Test
178                 {
179                         public C1Test class1;
180                         public C1Test class2;
181                         public Thread thread1;
182                         public Thread thread2;
183                         public bool T1ON ;
184                         public bool T2ON ;
185
186                         public C4Test()
187                         {
188                                 T1ON = false;
189                                 T2ON = false;
190                                 class1 = new C1Test();
191                                 class2 = new C1Test();
192                                 thread1 = new Thread(new ThreadStart(class1.TestMethod));
193                                 thread2 = new Thread(new ThreadStart(class2.TestMethod));
194                         }
195
196                         public void TestMethod1()
197                         {
198                                 thread1.Start();
199                                 TestUtil.WaitForAlive (thread1, "wait1");
200                                 T1ON = true;
201                                 thread2.Start();
202                                 TestUtil.WaitForAlive (thread2, "wait2");
203                                 T2ON = true;
204 #if MONO_FEATURE_THREAD_ABORT
205                                 thread1.Abort();
206 #else
207                                 thread1.Interrupt ();
208 #endif
209                                 TestUtil.WaitForNotAlive (thread1, "wait3");
210                                 T1ON = false;
211 #if MONO_FEATURE_THREAD_ABORT
212                                 thread2.Abort();
213 #else
214                                 thread2.Interrupt ();
215 #endif
216                                 TestUtil.WaitForNotAlive (thread2, "wait4");
217                                 T2ON = false;
218                         }
219                         
220                         public void TestMethod2()
221                         {
222                                 thread1.Start();
223                                 thread1.Join();
224                         }
225                 }
226
227                 [Test]
228                 public void TestCtor1()
229                 {
230                         C1Test test1 = new C1Test();
231                         Thread t = new Thread (new ThreadStart (test1.TestMethod));
232
233                         Assert.IsTrue (t.CurrentCulture.IsReadOnly, "CurrentCulture.IsReadOnly");
234                         Assert.IsFalse (t.IsAlive, "IsAlive");
235                         Assert.IsFalse (t.IsBackground, "IsBackground");
236                         Assert.IsNull (t.Name, "Name");
237                         Assert.AreEqual (ThreadState.Unstarted, t.ThreadState, "ThreadState");
238                 }
239
240                 [Test]
241                 [Category ("NotWorking")] // we're not sharing (read-only) CultureInfo
242                 public void CultureInfo_Shared_Across_Threads ()
243                 {
244                         Thread t = new Thread (TestCtor1);
245                         Assert.AreSame (t.CurrentCulture, t.CurrentUICulture, "Culture");
246
247                         Assert.AreSame (t.CurrentCulture, CultureInfo.CurrentCulture, "CultureInfo.CurrentCulture");
248                         Assert.AreSame (t.CurrentUICulture, CultureInfo.CurrentUICulture, "CultureInfo.CurrentUICulture");
249
250                         Assert.AreSame (t.CurrentCulture, Thread.CurrentThread.CurrentCulture, "Thread.CurrentThread.CurrentCulture");
251                         Assert.AreSame (t.CurrentUICulture, Thread.CurrentThread.CurrentUICulture, "Thread.CurrentThread.CurrentUICulture");
252                 }
253
254                 [Test] // bug #325566
255                 public void GetHashCodeTest ()
256                 {
257                         C1Test test1 = new C1Test ();
258                         Thread tA = new Thread (new ThreadStart (test1.TestMethod));
259                         int hA1 = tA.GetHashCode ();
260                         Assert.IsTrue (hA1 > 0, "#A1");
261                         tA.Start ();
262                         int hA2 = tA.GetHashCode ();
263                         Assert.AreEqual (hA1, hA2, "#A2");
264                         tA.Join ();
265                         int hA3 = tA.GetHashCode ();
266                         Assert.AreEqual (hA1, hA3, "#A3");
267                         Assert.AreEqual (hA1, tA.ManagedThreadId, "#A4");
268
269                         test1 = new C1Test ();
270                         Thread tB = new Thread (new ThreadStart (test1.TestMethod));
271                         int hB1 = tB.GetHashCode ();
272                         Assert.IsTrue (hB1 > 0, "#B1");
273                         tB.Start ();
274                         int hB2 = tB.GetHashCode ();
275                         Assert.AreEqual (hB1, hB2, "#B2");
276                         tB.Join ();
277                         int hB3 = tB.GetHashCode ();
278                         Assert.AreEqual (hB1, hB3, "#B3");
279                         Assert.AreEqual (hB1, tB.ManagedThreadId, "#B4");
280                         Assert.IsFalse (hA2 == hB2, "#B5");
281                 }
282
283                 [Test] // bug #82700
284                 public void ManagedThreadId ()
285                 {
286                         C1Test test1 = new C1Test ();
287                         Thread t1 = new Thread (new ThreadStart (test1.TestMethod));
288                         int mtA1 = t1.ManagedThreadId;
289                         t1.Start ();
290                         int mtA2 = t1.ManagedThreadId;
291                         t1.Join ();
292                         int mtA3 = t1.ManagedThreadId;
293                         Assert.AreEqual (mtA1, mtA2, "#A1");
294                         Assert.AreEqual (mtA2, mtA3, "#A2");
295
296                         test1 = new C1Test ();
297                         Thread t2 = new Thread (new ThreadStart (test1.TestMethod));
298                         int mtB1 = t2.ManagedThreadId;
299                         t2.Start ();
300                         int mtB2 = t2.ManagedThreadId;
301                         t2.Join ();
302                         int mtB3 = t2.ManagedThreadId;
303                         Assert.AreEqual (mtB1, mtB2, "#B1");
304                         Assert.AreEqual (mtB2, mtB3, "#B2");
305                         Assert.IsFalse (mtB1 == mtA1, "#B3");
306                 }
307
308                 [Test]
309                 [Category ("NotDotNet")] // it hangs.
310                 public void TestStart()
311                 {
312                 {
313                         C1Test test1 = new C1Test();
314                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
315                         TestThread.Start();
316                         TestThread.Join();
317                         Assert.AreEqual (10, test1.cnt, "#1");
318                 }
319                 {
320                         C2Test test1 = new C2Test();
321                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
322                         TestThread.Start();
323 #if MONO_FEATURE_THREAD_ABORT
324                         TestThread.Abort();
325 #else
326                         TestThread.Interrupt ();
327 #endif
328                         try {
329                                 TestThread.Start();
330                                 Assert.Fail ("#2");
331                         } catch (ThreadStateException) {
332                         }
333                 }
334                 {
335                         C2Test test1 = new C2Test();
336                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
337                         TestThread.Start();
338                         while (!test1.run) {
339                         }
340                         bool started = (TestThread.ThreadState == ThreadState.Running);
341                         Assert.AreEqual (started, test1.run, "#15 Thread Is not in the correct state: ");
342 #if MONO_FEATURE_THREAD_ABORT
343                         TestThread.Abort();
344 #else
345                         TestThread.Interrupt ();
346 #endif
347                 }
348                 }
349
350                 [Test]
351                 public void TestApartmentState ()
352                 {
353                         C2Test test1 = new C2Test();
354                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
355                         Assert.AreEqual (ApartmentState.Unknown, TestThread.ApartmentState, "#1");
356                         TestThread.Start();
357                         TestUtil.WaitForAlive (TestThread, "wait5");
358                         Assert.AreEqual (ApartmentState.MTA, TestThread.ApartmentState, "#2");
359 #if MONO_FEATURE_THREAD_ABORT
360                         TestThread.Abort();
361 #else
362                         TestThread.Interrupt ();
363 #endif
364                 }
365
366                 [Test]
367                 [Category ("NotWorking")] // setting the priority of a Thread before it is started isn't implemented in Mono yet
368                 public void TestPriority1()
369                 {
370                         C2Test test1 = new C2Test();
371                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
372                         try {
373                                 TestThread.Priority=ThreadPriority.BelowNormal;
374                                 ThreadPriority before = TestThread.Priority;
375                                 Assert.AreEqual (ThreadPriority.BelowNormal, before, "#40 Unexpected priority before thread start: ");
376                                 TestThread.Start();
377                                 TestUtil.WaitForAlive (TestThread, "wait7");
378                                 ThreadPriority after = TestThread.Priority;
379                                 Assert.AreEqual (before, after, "#41 Unexpected Priority Change: ");
380                         } finally {
381 #if MONO_FEATURE_THREAD_ABORT
382                                 TestThread.Abort();
383 #else
384                                 TestThread.Interrupt ();
385 #endif
386                         }
387                 }
388
389 #if MONO_FEATURE_THREAD_ABORT
390                 [Test]
391                 [Category ("NotDotNet")] // on MS, Thread is still in AbortRequested state when Start is invoked
392                 public void AbortUnstarted ()
393                 {
394                         C2Test test1 = new C2Test();
395                         Thread th = new Thread (new ThreadStart (test1.TestMethod));
396                         th.Abort ();
397                         th.Start ();
398                 }
399 #endif
400
401                 [Test]
402                 [Category ("NotDotNet")] // on MS, ThreadState is immediately Stopped after Abort
403                 [Category ("NotWorking")] // this is a MonoTODO -> no support for Priority
404                 public void TestPriority2()
405                 {
406                         C2Test test1 = new C2Test();
407                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
408                         try {
409                                 Assert.AreEqual (ThreadPriority.Normal, TestThread.Priority, "#42 Incorrect Priority in New thread: ");
410                                 TestThread.Start();
411                                 TestUtil.WaitForAliveOrStop (TestThread, "wait8");
412                                 Assert.AreEqual (ThreadPriority.Normal, TestThread.Priority, "#43 Incorrect Priority in Started thread: ");
413                         } finally {
414 #if MONO_FEATURE_THREAD_ABORT
415                                 TestThread.Abort();
416 #else
417                                 TestThread.Interrupt ();
418 #endif
419                         }
420                         Assert.AreEqual (ThreadPriority.Normal, TestThread.Priority, "#44 Incorrect Priority in Aborted thread: ");
421                 }
422
423                 [Test]
424                 [Category ("NotWorking")] // this is a MonoTODO -> no support for Priority
425                 public void TestPriority3()
426                 {
427                         C2Test test1 = new C2Test();
428                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
429                         try {
430                                 TestThread.Start();
431                                 TestThread.Priority = ThreadPriority.Lowest;
432                                 Assert.AreEqual (ThreadPriority.Lowest, TestThread.Priority, "#45A Incorrect Priority:");
433                                 TestThread.Priority = ThreadPriority.BelowNormal;
434                                 Assert.AreEqual (ThreadPriority.BelowNormal, TestThread.Priority, "#45B Incorrect Priority:");
435                                 TestThread.Priority = ThreadPriority.Normal;
436                                 Assert.AreEqual (ThreadPriority.Normal, TestThread.Priority, "#45C Incorrect Priority:");
437                                 TestThread.Priority = ThreadPriority.AboveNormal;
438                                 Assert.AreEqual (ThreadPriority.AboveNormal, TestThread.Priority, "#45D Incorrect Priority:");
439                                 TestThread.Priority = ThreadPriority.Highest;
440                                 Assert.AreEqual (ThreadPriority.Highest, TestThread.Priority, "#45E Incorrect Priority:");
441                         }
442                         finally {
443 #if MONO_FEATURE_THREAD_ABORT
444                                 TestThread.Abort();
445 #else
446                                 TestThread.Interrupt ();
447 #endif
448                         }
449                 }
450
451                 [Test]
452                 public void TestUndivisibleByPageSizeMaxStackSize ()
453                 {
454                         const int undivisible_stacksize = 1048573;
455
456                         var thread = new Thread (new ThreadStart (delegate {}), undivisible_stacksize);
457                         thread.Start ();
458                         thread.Join ();
459                 }
460
461                 [Test]
462                 public void TestIsBackground1 ()
463                 {
464                         C2Test test1 = new C2Test();
465                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
466                         try {
467                                 TestThread.Start();
468                                 TestUtil.WaitForAlive (TestThread, "wait9");
469                                 bool state = TestThread.IsBackground;
470                                 Assert.IsFalse (state, "#51 IsBackground not set at the default state: ");
471                         } finally {
472 #if MONO_FEATURE_THREAD_ABORT
473                                 TestThread.Abort();
474 #else
475                                 TestThread.Interrupt ();
476 #endif
477                         }
478                 }
479
480                 [Test]
481                 public void TestIsBackground2 ()
482                 {
483                         C2Test test1 = new C2Test();
484                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
485                         TestThread.IsBackground = true;
486                         try {
487                                 TestThread.Start();
488                         } finally {
489 #if MONO_FEATURE_THREAD_ABORT
490                                 TestThread.Abort();
491 #else
492                                 TestThread.Interrupt ();
493 #endif
494                         }
495                         
496                         if (TestThread.IsAlive) {
497                                 try {
498                                         Assert.IsTrue (TestThread.IsBackground, "#52 Is Background Changed to Start ");
499                                 } catch (ThreadStateException) {
500                                         // Ignore if thread died meantime
501                                 }
502                         }
503                 }
504
505                 [Test]
506                 public void TestName()
507                 {
508                         C2Test test1 = new C2Test();
509                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
510                         try {
511                                 TestThread.Start();
512                                 TestUtil.WaitForAlive (TestThread, "wait10");
513                                 string name = TestThread.Name;
514                                 Assert.IsNull (name, "#61 Name set when mustn't be set: ");
515                                 string newname = "Testing....";
516                                 TestThread.Name = newname;
517                                 Assert.AreEqual (newname, TestThread.Name, "#62 Name not set when must be set: ");
518                         } finally {
519 #if MONO_FEATURE_THREAD_ABORT
520                                 TestThread.Abort();
521 #else
522                                 TestThread.Interrupt ();
523 #endif
524                         }
525                 }
526
527                 [Test]
528                 public void Name ()
529                 {
530                         Thread t = new Thread (new ThreadStart (Name));
531                         Assert.IsNull (t.Name, "Name-1");
532                         t.Name = null;
533                         Assert.IsNull (t.Name, "Name-2");
534                 }
535
536                 [Test]
537                 [ExpectedException (typeof (InvalidOperationException))]
538                 public void Rename ()
539                 {
540                         Thread t = new Thread (new ThreadStart (Rename));
541                         t.Name = "a";
542                         t.Name = "b";
543                 }
544
545                 [Test]
546                 public void TestNestedThreads1()
547                 {
548                         C3Test test1 = new C3Test();
549                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod1));
550                         try {
551                                 TestThread.Start();
552                                 TestUtil.WaitForAlive (TestThread, "wait11");
553                         } finally {
554 #if MONO_FEATURE_THREAD_ABORT
555                                 TestThread.Abort();
556 #else
557                                 TestThread.Interrupt ();
558 #endif
559                         }
560                 }
561
562                 [Test]
563                 public void TestNestedThreads2()
564                 {
565                         C4Test test1 = new C4Test();
566                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod1));
567                         try {
568                                 TestThread.Start();
569                         } finally {
570 #if MONO_FEATURE_THREAD_ABORT
571                                 TestThread.Abort();
572 #else
573                                 TestThread.Interrupt ();
574 #endif
575                         }
576                 }
577
578                 [Test]
579                 public void TestJoin1()
580                 {
581                         C1Test test1 = new C1Test();
582                         C1Test test2 = new C1Test();
583                         Thread thread1 = new Thread(new ThreadStart(test1.TestMethod));
584                         Thread thread2 = new Thread(new ThreadStart(test1.TestMethod2));
585                         try {
586                                 thread1.Start();
587                                 thread2.Start();
588                                 thread2.Join();
589                         } finally {
590 #if MONO_FEATURE_THREAD_ABORT
591                                 thread1.Abort();
592                                 thread2.Abort();
593 #else
594                                 thread1.Interrupt ();
595                                 thread2.Interrupt ();
596 #endif
597                         }
598                 }
599
600                 [Test]
601                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
602                 public void Join_Int32_Negative ()
603                 {
604                         // -1 is Timeout.Infinite
605                         Thread.CurrentThread.Join (-2);
606                 }
607
608                 [Test]
609                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
610                 public void Join_TimeSpan_Negative ()
611                 {
612                         Thread.CurrentThread.Join (Negative);
613                 }
614
615                 [Test]
616                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
617                 public void Join_TimeSpan_TooLarge ()
618                 {
619                         Thread.CurrentThread.Join (TooLarge);
620                 }
621
622                 [Test]
623                 public void Join_TimeSpan_SmallNegative ()
624                 {
625                         Thread.CurrentThread.Join (SmallNegative);
626                 }
627
628                 [Test]
629                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
630                 public void Sleep_Int32_Negative ()
631                 {
632                         // -1 is Timeout.Infinite
633                         Thread.Sleep (-2);
634                 }
635
636                 [Test]
637                 public void Sleep_TimeSpan_SmallNegative ()
638                 {
639                         Thread.Sleep (SmallNegative);
640                 }
641
642                 [Test]
643                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
644                 public void Sleep_TimeSpan_Negative ()
645                 {
646                         Thread.Sleep (Negative);
647                 }
648
649                 [Test]
650                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
651                 public void Sleep_TimeSpan_TooLarge ()
652                 {
653                         Thread.Sleep (TooLarge);
654                 }
655
656                 [Test]
657                 public void SpinWait ()
658                 {
659                         // no exception for negative numbers
660                         Thread.SpinWait (Int32.MinValue);
661                         Thread.SpinWait (0);
662                 }
663
664                 [Test]
665                 public void TestThreadState ()
666                 {
667                         //TODO: Test The rest of the possible transitions
668                         C2Test test1 = new C2Test();
669                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
670                         Assert.AreEqual (ThreadState.Unstarted, TestThread.ThreadState, "#101 Wrong Thread State");
671                         try {
672                                 TestThread.Start();
673                                 //while(!TestThread.IsAlive); //In the MS Documentation this is not necessary
674                                                                                           //but in the MS SDK it is
675                                 Assert.IsTrue (TestThread.ThreadState == ThreadState.Running || (TestThread.ThreadState & ThreadState.Unstarted) != 0,
676                                         "#102 Wrong Thread State: " + TestThread.ThreadState.ToString ());
677                         } finally {
678 #if MONO_FEATURE_THREAD_ABORT
679                                 TestThread.Abort();
680 #else
681                                 TestThread.Interrupt ();
682 #endif
683                         }
684                         
685                         TestUtil.WaitForNotAlive (TestThread, "wait12");
686                         // Docs say state will be Stopped, but Aborted happens sometimes (?)
687                         Assert.IsTrue ((ThreadState.Stopped & TestThread.ThreadState) != 0 || (ThreadState.Aborted & TestThread.ThreadState) != 0,
688                                 "#103 Wrong Thread State: " + TestThread.ThreadState.ToString ());
689                 }
690
691                 [Test]
692                 [Ignore ("see comment below.")]
693                 public void CurrentPrincipal_PrincipalPolicy_NoPrincipal () 
694                 {
695                         // note: switching from PrincipalPolicy won't work inside the same thread
696                         // because as soon as a Principal object is created the Policy doesn't matter anymore
697                         Thread t = new Thread (new ThreadStart (ThreadedPrincipalTest.NoPrincipal));
698                         try {
699                                 t.Start ();
700                                 t.Join ();
701                         } catch {
702 #if MONO_FEATURE_THREAD_ABORT
703                                 t.Abort ();
704 #else
705                                 t.Interrupt ();
706 #endif
707                         }
708                 }
709
710                 [Test]
711                 [Ignore ("see comment below.")]
712                 public void CurrentPrincipal_PrincipalPolicy_UnauthenticatedPrincipal () 
713                 {
714                         // note: switching from PrincipalPolicy won't work inside the same thread
715                         // because as soon as a Principal object is created the Policy doesn't matter anymore
716                         Thread t = new Thread (new ThreadStart (ThreadedPrincipalTest.UnauthenticatedPrincipal));
717                         try {
718                                 t.Start ();
719                                 t.Join ();
720                         } catch {
721 #if MONO_FEATURE_THREAD_ABORT
722                                 t.Abort ();
723 #else
724                                 t.Interrupt ();
725 #endif
726                         }
727                 }
728
729                 [Test]
730                 public void CurrentPrincipal_PrincipalPolicy_WindowsPrincipal () 
731                 {
732                         // note: switching from PrincipalPolicy won't work inside the same thread
733                         // because as soon as a Principal object is created the Policy doesn't matter anymore
734                         Thread t = new Thread (new ThreadStart (ThreadedPrincipalTest.WindowsPrincipal));
735                         try {
736                                 t.Start ();
737                                 t.Join ();
738                         } catch {
739 #if MONO_FEATURE_THREAD_ABORT
740                                 t.Abort ();
741 #else
742                                 t.Interrupt ();
743 #endif
744                         }
745                 }
746                 
747                 [Test]
748                 public void IPrincipal_CopyOnNewThread () 
749                 {
750                         Thread.CurrentPrincipal = new GenericPrincipal (new GenericIdentity ("bad"), null);
751                         Thread t = new Thread (new ThreadStart (ThreadedPrincipalTest.CopyOnNewThread));
752                         try {
753                                 Thread.CurrentPrincipal = new GenericPrincipal (new GenericIdentity ("good"), null);
754                                 t.Start ();
755                                 t.Join ();
756                         } catch {
757 #if MONO_FEATURE_THREAD_ABORT
758                                 t.Abort ();
759 #else
760                                 t.Interrupt ();
761 #endif
762                         }
763                 }
764
765                 int counter = 0;
766
767 #if MONO_FEATURE_THREAD_SUSPEND_RESUME
768                 [Test]
769                 public void TestSuspend ()
770                 {
771                         Thread t = new Thread (new ThreadStart (DoCount));
772                         t.IsBackground = true;
773                         t.Start ();
774                         
775                         CheckIsRunning ("t1", t);
776                         
777                         t.Suspend ();
778                         WaitSuspended ("t2", t);
779                         
780                         CheckIsNotRunning ("t3", t);
781                         
782                         t.Resume ();
783                         WaitResumed ("t4", t);
784                         
785                         CheckIsRunning ("t5", t);
786                         
787                         t.Abort ();
788                         TestUtil.WaitForNotAlive (t, "wait13");
789                         CheckIsNotRunning ("t6", t);
790                 }
791 #endif
792                 
793 #if MONO_FEATURE_THREAD_SUSPEND_RESUME && MONO_FEATURE_THREAD_ABORT
794                 [Test]
795                 [Category("NotDotNet")] // On MS, ThreadStateException is thrown on Abort: "Thread is suspended; attempting to abort"
796                 public void TestSuspendAbort ()
797                 {
798                         Thread t = new Thread (new ThreadStart (DoCount));
799                         t.IsBackground = true;
800                         t.Start ();
801                         
802                         CheckIsRunning ("t1", t);
803                         
804                         t.Suspend ();
805                         WaitSuspended ("t2", t);
806                         
807                         CheckIsNotRunning ("t3", t);
808                         
809                         t.Abort ();
810                         
811                         int n=0;
812                         while (t.IsAlive && n < 200) {
813                                 Thread.Sleep (10);
814                                 n++;
815                         }
816
817                         Assert.IsTrue (n < 200, "Timeout while waiting for abort");
818                         
819                         CheckIsNotRunning ("t6", t);
820                 }
821 #endif
822
823                 [Test]
824                 public void Test_Interrupt ()
825                 {
826                         ManualResetEvent mre = new ManualResetEvent (false);
827                         bool interruptedExceptionThrown = false;
828
829                         ThreadPool.QueueUserWorkItem (Test_Interrupt_Worker, Thread.CurrentThread);
830
831                         try {
832                                 try {
833                                         mre.WaitOne (3000);
834                                 } finally {
835                                         try {
836                                                 mre.WaitOne (0);
837                                         } catch (ThreadInterruptedException) {
838                                                 Assert.Fail ("ThreadInterruptedException thrown twice");
839                                         }
840                                 }
841                         } catch (ThreadInterruptedException) {
842                                 interruptedExceptionThrown = true;
843                         }
844
845                         Assert.IsTrue (interruptedExceptionThrown, "ThreadInterruptedException expected.");
846                 }
847
848                 [Test]
849                 [ExpectedException (typeof (ArgumentNullException))]
850                 public void TestQueueUserWorkItemNullCallback ()
851                 {
852                         ThreadPool.QueueUserWorkItem (null, null);
853                 }
854
855                 private void Test_Interrupt_Worker (object o)
856                 {
857                         Thread t = o as Thread;
858                         Thread.Sleep (100);
859                         t.Interrupt ();
860                 }
861                 
862                 [Test]
863                 public void Test_InterruptCurrentThread ()
864                 {
865                         ManualResetEvent mre = new ManualResetEvent (false);
866                         bool interruptedExceptionThrown = false;
867
868                         Thread.CurrentThread.Interrupt ();
869                         try {
870                                 mre.WaitOne (0);
871                                 Assert.Fail ();
872                         } catch (ThreadInterruptedException) {
873                         }
874                 }
875
876                 [Test]
877                 public void GetNamedDataSlotTest ()
878                 {
879                         Assert.IsNotNull (Thread.GetNamedDataSlot ("te#st"), "#1");
880                         Assert.AreSame (Thread.GetNamedDataSlot ("te#st"), Thread.GetNamedDataSlot ("te#st"), "#2");
881                 }
882
883                 class DomainClass : MarshalByRefObject {
884                         Thread m_thread;
885                         bool success;
886
887                         public bool Run () {
888                                 m_thread = new Thread(ThreadProc);
889                                 m_thread.Start(Thread.CurrentThread);
890                                 m_thread.Join();
891                                 return success;
892                         }
893
894                         public void ThreadProc (object arg) {
895                                 success = m_thread == Thread.CurrentThread;
896                         }
897                 }
898
899 #if MONO_FEATURE_MULTIPLE_APPDOMAINS
900                 [Test]
901                 [Category ("NotDotNet")]
902                 public void CurrentThread_Domains ()
903                 {
904                         AppDomain ad = AppDomain.CreateDomain ("foo");
905                         ad.Load (typeof (DomainClass).Assembly.GetName ());
906                         var o = (DomainClass)ad.CreateInstanceAndUnwrap (typeof (DomainClass).Assembly.FullName, typeof (DomainClass).FullName);
907                         Assert.IsTrue (o.Run ());
908                         AppDomain.Unload (ad);
909                 }
910 #endif // MONO_FEATURE_MULTIPLE_APPDOMAINS
911
912                 [Test]
913                 public void SetNameInThreadPoolThread ()
914                 {
915                         for (int i = 0; i < 10; ++i) {
916                                 Task t = Task.Run (delegate () {
917                                         Thread.CurrentThread.Name = "x/" + i;
918                                         Assert.AreEqual (Thread.CurrentThread.Name, "x/" + i, "#1");
919
920                                         try {
921                                                 Thread.CurrentThread.Name = "y/" + i;
922                                                 Assert.Fail ("#2");
923                                         } catch (InvalidOperationException) {
924                                         }
925                                 });
926
927                                 t.Wait ();
928                         }
929                 }
930
931                 void CheckIsRunning (string s, Thread t)
932                 {
933                         int c = counter;
934                         Thread.Sleep (100);
935                         Assert.IsTrue (counter > c, s);
936                 }
937                 
938                 void CheckIsNotRunning (string s, Thread t)
939                 {
940                         int c = counter;
941                         Thread.Sleep (100);
942                         Assert.AreEqual (counter, c, s);
943                 }
944                 
945                 void WaitSuspended (string s, Thread t)
946                 {
947                         int n=0;
948                         ThreadState state = t.ThreadState;
949                         while ((state & ThreadState.Suspended) == 0) {
950                                 Assert.IsTrue ((state & ThreadState.SuspendRequested) != 0, s + ": expected SuspendRequested state");
951                                 Thread.Sleep (10);
952                                 n++;
953                                 Assert.IsTrue (n < 100, s + ": failed to suspend");
954                                 state = t.ThreadState;
955                         }
956                         Assert.IsTrue ((state & ThreadState.SuspendRequested) == 0, s + ": SuspendRequested state not expected");
957                 }
958                 
959                 void WaitResumed (string s, Thread t)
960                 {
961                         int n=0;
962                         while ((t.ThreadState & ThreadState.Suspended) != 0) {
963                                 Thread.Sleep (10);
964                                 n++;
965                                 Assert.IsTrue (n < 100, s + ": failed to resume");
966                         }
967                 }
968                 
969                 public void DoCount ()
970                 {
971                         while (true) {
972                                 counter++;
973                                 Thread.Sleep (1);
974                         }
975                 }
976         }
977
978         [TestFixture]
979         public class ThreadStateTest {
980                 void Start ()
981                 {
982                 }
983
984                 [Test] // bug #81720
985                 public void IsBackGround ()
986                 {
987                         Thread t1 = new Thread (new ThreadStart (Start));
988                         Assert.AreEqual (ThreadState.Unstarted, t1.ThreadState, "#A1");
989                         Assert.IsFalse (t1.IsBackground, "#A2");
990                         t1.Start ();
991                         t1.Join ();
992                         Assert.AreEqual (ThreadState.Stopped, t1.ThreadState, "#A3");
993
994                         try {
995                                 bool isBackGround = t1.IsBackground;
996                                 Assert.Fail ("#A4: " + isBackGround.ToString ());
997                         } catch (ThreadStateException ex) {
998                                 Assert.AreEqual (typeof (ThreadStateException), ex.GetType (), "#A5");
999                                 Assert.IsNull (ex.InnerException, "#A6");
1000                                 Assert.IsNotNull (ex.Message, "#A7");
1001                         }
1002
1003                         Thread t2 = new Thread (new ThreadStart (Start));
1004                         Assert.AreEqual (ThreadState.Unstarted, t2.ThreadState, "#B1");
1005                         t2.IsBackground = true;
1006                         Assert.AreEqual (ThreadState.Unstarted | ThreadState.Background, t2.ThreadState, "#B2");
1007                         Assert.IsTrue (t2.IsBackground, "#B3");
1008                         t2.Start ();
1009                         t2.Join ();
1010                         Assert.AreEqual (ThreadState.Stopped, t2.ThreadState, "#B4");
1011
1012                         try {
1013                                 bool isBackGround = t2.IsBackground;
1014                                 Assert.Fail ("#B5: " + isBackGround.ToString ());
1015                         } catch (ThreadStateException ex) {
1016                                 Assert.AreEqual (typeof (ThreadStateException), ex.GetType (), "#B6");
1017                                 Assert.IsNull (ex.InnerException, "#B7");
1018                                 Assert.IsNotNull (ex.Message, "#B8");
1019                         }
1020                 }
1021         }
1022
1023         [TestFixture]
1024         [Serializable]
1025         public class ThreadTest_ManagedThreadId
1026         {
1027                 AppDomain ad1;
1028                 AppDomain ad2;
1029                 MBRO mbro = new MBRO ();
1030
1031                 class MBRO : MarshalByRefObject {
1032                         public int id_a1;
1033                         public int id_b1;
1034                         public int id_b2;
1035                         public string ad_a1;
1036                         public string ad_b1;
1037                         public string ad_b2;
1038                         public string message;
1039                 }
1040 #if !MOBILE
1041                 [Test]
1042                 public void ManagedThreadId_AppDomains ()
1043                 {
1044                         AppDomain currentDomain = AppDomain.CurrentDomain;
1045                         ad1 = AppDomain.CreateDomain ("AppDomain 1", currentDomain.Evidence, currentDomain.SetupInformation);
1046                         ad2 = AppDomain.CreateDomain ("AppDomain 2", currentDomain.Evidence, currentDomain.SetupInformation);
1047
1048                         Thread a = new Thread (ThreadA);
1049                         Thread b = new Thread (ThreadB);
1050                         // execute on AppDomain 1 thread A
1051                         // execute on AppDomain 2 thread B
1052                         // execute on AppDomain 1 thread B - must have same ManagedThreadId as Ad 2 on thread B
1053                         a.Start ();
1054                         a.Join ();
1055                         b.Start ();
1056                         b.Join ();
1057
1058                         AppDomain.Unload (ad1);
1059                         AppDomain.Unload (ad2);
1060
1061                         if (mbro.message != null)
1062                                 Assert.Fail (mbro.message);
1063
1064                         // Console.WriteLine ("Done id_a1: {0} id_b1: {1} id_b2: {2} ad_a1: {3} ad_b1: {4} ad_b2: {5}", mbro.id_a1, mbro.id_b1, mbro.id_b2, mbro.ad_a1, mbro.ad_b1, mbro.ad_b2);
1065
1066                         Assert.AreEqual ("AppDomain 1", mbro.ad_a1, "Name #1");
1067                         Assert.AreEqual ("AppDomain 1", mbro.ad_b1, "Name #2");
1068                         Assert.AreEqual ("AppDomain 2", mbro.ad_b2, "Name #3");
1069
1070                         Assert.AreNotEqual (mbro.id_a1, mbro.id_b1, "Id #1");
1071                         Assert.AreNotEqual (mbro.id_a1, mbro.id_b2, "Id #2");
1072                         Assert.AreEqual (mbro.id_b1, mbro.id_b2, "Id #3");
1073
1074                         Assert.AreNotEqual (mbro.id_a1, Thread.CurrentThread.ManagedThreadId, "Id #4");
1075                         Assert.AreNotEqual (mbro.id_b1, Thread.CurrentThread.ManagedThreadId, "Id #5");
1076                         Assert.AreNotEqual (mbro.id_b2, Thread.CurrentThread.ManagedThreadId, "Id #6");
1077                         Assert.AreNotEqual (mbro.ad_a1, AppDomain.CurrentDomain.FriendlyName, "Name #4");
1078                         Assert.AreNotEqual (mbro.ad_b1, AppDomain.CurrentDomain.FriendlyName, "Name #5");
1079                         Assert.AreNotEqual (mbro.ad_b2, AppDomain.CurrentDomain.FriendlyName, "Name #6");
1080                 }
1081 #endif
1082                 void A1 ()
1083                 {
1084                         mbro.id_a1 = Thread.CurrentThread.ManagedThreadId;
1085                         mbro.ad_a1 = AppDomain.CurrentDomain.FriendlyName;
1086                 }
1087                 
1088                 void B2 ()
1089                 {
1090                         mbro.id_b2 = Thread.CurrentThread.ManagedThreadId;
1091                         mbro.ad_b2 = AppDomain.CurrentDomain.FriendlyName;
1092                 }
1093
1094                 void B1 ()
1095                 {
1096                         mbro.id_b1 = Thread.CurrentThread.ManagedThreadId;
1097                         mbro.ad_b1 = AppDomain.CurrentDomain.FriendlyName;
1098                 }
1099
1100                 void ThreadA (object obj)
1101                 {
1102                         // Console.WriteLine ("ThreadA");
1103                         try {
1104                                 ad1.DoCallBack (A1);
1105                         } catch (Exception ex) {
1106                                 mbro.message = string.Format ("ThreadA exception: {0}", ex);
1107                         }
1108                         // Console.WriteLine ("ThreadA Done");
1109                 }
1110
1111                 void ThreadB (object obj)
1112                 {
1113                         // Console.WriteLine ("ThreadB");
1114                         try {
1115                                 ad2.DoCallBack (B2);
1116                                 ad1.DoCallBack (B1);
1117                         } catch (Exception ex) {
1118                                 mbro.message = string.Format ("ThreadB exception: {0}", ex);
1119                         }
1120                         // Console.WriteLine ("ThreadB Done");
1121                 }
1122         }
1123
1124         [TestFixture]
1125         public class ThreadApartmentTest
1126         {
1127                 void Start ()
1128                 {
1129                 }
1130
1131                 [Test] // bug #81658
1132                 public void ApartmentState_StoppedThread ()
1133                 {
1134                         Thread t1 = new Thread (new ThreadStart (Start));
1135                         t1.Start ();
1136                         t1.Join ();
1137                         try {
1138                                 ApartmentState state = t1.ApartmentState;
1139                                 Assert.Fail ("#A1: " + state.ToString ());
1140                         } catch (ThreadStateException ex) {
1141                                 Assert.AreEqual (typeof (ThreadStateException), ex.GetType (), "#A2");
1142                                 Assert.IsNull (ex.InnerException, "#A3");
1143                                 Assert.IsNotNull (ex.Message, "#A4");
1144                         }
1145
1146                         Thread t2 = new Thread (new ThreadStart (Start));
1147                         t2.IsBackground = true;
1148                         t2.Start ();
1149                         t2.Join ();
1150                         try {
1151                                 ApartmentState state = t2.ApartmentState;
1152                                 Assert.Fail ("#B1: " + state.ToString ());
1153                         } catch (ThreadStateException ex) {
1154                                 Assert.AreEqual (typeof (ThreadStateException), ex.GetType (), "#B2");
1155                                 Assert.IsNull (ex.InnerException, "#B3");
1156                                 Assert.IsNotNull (ex.Message, "#B4");
1157                         }
1158                 }
1159
1160                 [Test]
1161                 public void ApartmentState_BackGround ()
1162                 {
1163                         Thread t1 = new Thread (new ThreadStart (Start));
1164                         t1.IsBackground = true;
1165                         Assert.AreEqual (ApartmentState.Unknown, t1.ApartmentState, "#1");
1166                         t1.ApartmentState = ApartmentState.STA;
1167                         Assert.AreEqual (ApartmentState.STA, t1.ApartmentState, "#2");
1168                 }
1169
1170                 [Test]
1171                 public void TestApartmentState ()
1172                 {
1173                         Thread t1 = new Thread (new ThreadStart (Start));
1174                         Thread t2 = new Thread (new ThreadStart (Start));
1175                         Thread t3 = new Thread (new ThreadStart (Start));
1176
1177                         Assert.AreEqual (ApartmentState.Unknown, t1.ApartmentState, "Thread1 Default");
1178                         Assert.AreEqual (ApartmentState.Unknown, t2.ApartmentState, "Thread2 Default");
1179                         Assert.AreEqual (ApartmentState.Unknown, t3.ApartmentState, "Thread3 Default");
1180
1181                         t1.ApartmentState = ApartmentState.STA;
1182                         Assert.AreEqual (ApartmentState.STA, t1.ApartmentState, "Thread1 Set Once");
1183                         t1.ApartmentState = ApartmentState.MTA;
1184                         Assert.AreEqual (ApartmentState.STA, t1.ApartmentState, "Thread1 Set Twice");
1185
1186                         t2.ApartmentState = ApartmentState.MTA;
1187                         Assert.AreEqual (ApartmentState.MTA, t2.ApartmentState, "Thread2 Set Once");
1188                         t2.ApartmentState = ApartmentState.STA;
1189                         Assert.AreEqual (ApartmentState.MTA, t2.ApartmentState, "Thread2 Set Twice");
1190
1191                         bool exception_occured = false;
1192                         try {
1193                                 t3.ApartmentState = ApartmentState.Unknown;
1194                         }
1195                         catch (Exception) {
1196                                 exception_occured = true;
1197                         }
1198                         Assert.AreEqual (ApartmentState.Unknown, t3.ApartmentState, "Thread3 Set Invalid");
1199                         Assert.IsFalse (exception_occured, "Thread3 Set Invalid Exception Occured");
1200
1201                         t1.Start ();
1202                         exception_occured = false;
1203                         try {
1204                                 t1.ApartmentState = ApartmentState.STA;
1205                         }
1206                         catch (Exception) {
1207                                 exception_occured = true;
1208                         }
1209                         Assert.IsTrue (exception_occured, "Thread1 Started Invalid Exception Occured");
1210                 }
1211
1212                 [Test]
1213                 public void TestSetApartmentStateSameState ()
1214                 {
1215                         Thread t1 = new Thread (new ThreadStart (Start));
1216                         t1.SetApartmentState (ApartmentState.STA);
1217                         Assert.AreEqual (ApartmentState.STA, t1.ApartmentState, "Thread1 Set Once");
1218
1219                         t1.SetApartmentState (ApartmentState.STA);
1220                         Assert.AreEqual (ApartmentState.STA, t1.ApartmentState, "Thread1 Set twice");
1221                 }
1222
1223                 [Test]
1224                 [ExpectedException(typeof(InvalidOperationException))]
1225                 public void TestSetApartmentStateDiffState ()
1226                 {
1227                         Thread t1 = new Thread (new ThreadStart (Start));
1228                         t1.SetApartmentState (ApartmentState.STA);
1229                         Assert.AreEqual (ApartmentState.STA, t1.ApartmentState, "Thread1 Set Once");
1230
1231                         t1.SetApartmentState (ApartmentState.MTA);
1232                 }
1233
1234                 [Test]
1235                 public void TestTrySetApartmentState ()
1236                 {
1237                         Thread t1 = new Thread (new ThreadStart (Start));
1238                         t1.SetApartmentState (ApartmentState.STA);
1239                         Assert.AreEqual (ApartmentState.STA, t1.ApartmentState, "#1");
1240
1241                         bool result = t1.TrySetApartmentState (ApartmentState.MTA);
1242                         Assert.IsFalse (result, "#2");
1243
1244                         result = t1.TrySetApartmentState (ApartmentState.STA);
1245                         Assert.IsTrue (result, "#3");
1246                 }
1247
1248                 [Test]
1249                 public void TestTrySetApartmentStateRunning ()
1250                 {
1251                         Thread t1 = new Thread (new ThreadStart (Start));
1252                         t1.SetApartmentState (ApartmentState.STA);
1253                         Assert.AreEqual (ApartmentState.STA, t1.ApartmentState, "#1");
1254
1255                         t1.Start ();
1256
1257                         try {
1258                                 t1.TrySetApartmentState (ApartmentState.STA);
1259                                 Assert.Fail ("#2");
1260                         } catch (ThreadStateException) {
1261                         }
1262
1263                         t1.Join ();
1264                 }
1265
1266                 [Test]
1267                 public void Volatile () {
1268                         double v3 = 55667;
1269                         Thread.VolatileWrite (ref v3, double.MaxValue);
1270                         Assert.AreEqual (v3, double.MaxValue);
1271
1272                         float v4 = 1;
1273                         Thread.VolatileWrite (ref v4, float.MaxValue);
1274                         Assert.AreEqual (v4, float.MaxValue);
1275                 }
1276
1277                 [Test]
1278                 public void Culture ()
1279                 {
1280                         Assert.IsNotNull (Thread.CurrentThread.CurrentCulture, "CurrentCulture");
1281                         Assert.IsNotNull (Thread.CurrentThread.CurrentUICulture, "CurrentUICulture");
1282                 }
1283
1284                 [Test]
1285                 public void ThreadStartSimple ()
1286                 {
1287                         int i = 0;
1288                         Thread t = new Thread (delegate () {
1289                                 // ensure the NSAutoreleasePool works
1290                                 i++;
1291                         });
1292                         t.Start ();
1293                         t.Join ();
1294                         Assert.AreEqual (1, i, "ThreadStart");
1295                 }
1296
1297                 [Test]
1298                 public void ParametrizedThreadStart ()
1299                 {
1300                         int i = 0;
1301                         object arg = null;
1302                         Thread t = new Thread (delegate (object obj) {
1303                                 // ensure the NSAutoreleasePool works
1304                                 i++;
1305                                 arg = obj;
1306                         });
1307                         t.Start (this);
1308                         t.Join ();
1309
1310                         Assert.AreEqual (1, i, "ParametrizedThreadStart");
1311                         Assert.AreEqual (this, arg, "obj");     
1312                 }               
1313
1314                 [Test]
1315                 public void SetNameTpThread () {
1316                         ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc));
1317                 }
1318
1319                 static void ThreadProc(Object stateInfo) {
1320                         Thread.CurrentThread.Name = "My Worker";
1321                 }
1322
1323                 [Test]
1324                 public void GetStackTraces () {
1325                         var m = typeof (Thread).GetMethod ("Mono_GetStackTraces", BindingFlags.NonPublic|BindingFlags.Static);
1326                         if (m != null) {
1327                                 var res = (Dictionary<Thread,SD.StackTrace>)typeof (Thread).GetMethod ("Mono_GetStackTraces", BindingFlags.NonPublic|BindingFlags.Static).Invoke (null, null);
1328                                 foreach (var t in res.Keys) {
1329                                         var st = res [t].ToString ();
1330                                 }
1331                         }
1332                 }
1333         }
1334
1335         public class TestUtil
1336         {
1337                 public static void WaitForNotAlive (Thread t, string s)
1338                 {
1339                         WhileAlive (t, true, s);
1340                 }
1341                 
1342                 public static void WaitForAlive (Thread t, string s)
1343                 {
1344                         WhileAlive (t, false, s);
1345                 }
1346                 
1347                 public static bool WaitForAliveOrStop (Thread t, string s)
1348                 {
1349                         return WhileAliveOrStop (t, false, s);
1350                 }
1351                 
1352                 public static void WhileAlive (Thread t, bool alive, string s)
1353                 {
1354                         DateTime ti = DateTime.Now;
1355                         while (t.IsAlive == alive) {
1356                                 if ((DateTime.Now - ti).TotalSeconds > 10) {
1357                                         if (alive) Assert.Fail ("Timeout while waiting for not alive state. " + s);
1358                                         else Assert.Fail ("Timeout while waiting for alive state. " + s);
1359                                 }
1360                         }
1361                 }
1362
1363                 public static bool WhileAliveOrStop (Thread t, bool alive, string s)
1364                 {
1365                         DateTime ti = DateTime.Now;
1366                         while (t.IsAlive == alive) {
1367                                 if (t.ThreadState == ThreadState.Stopped)
1368                                         return false;
1369
1370                                 if ((DateTime.Now - ti).TotalSeconds > 10) {
1371                                         if (alive) Assert.Fail ("Timeout while waiting for not alive state. " + s);
1372                                         else Assert.Fail ("Timeout while waiting for alive state. " + s);
1373                                 }
1374                         }
1375
1376                         return true;
1377                 }
1378         }
1379 }