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