Merge pull request #1936 from esdrubal/DotNetRelativeOrAbsolute
[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                         ManualResetEvent mre = new ManualResetEvent (false);
804                         bool interruptedExceptionThrown = false;
805
806                         ThreadPool.QueueUserWorkItem (Test_Interrupt_Worker, Thread.CurrentThread);
807
808                         try {
809                                 try {
810                                         mre.WaitOne (3000);
811                                 } finally {
812                                         try {
813                                                 mre.WaitOne (0);
814                                         } catch (ThreadInterruptedException) {
815                                                 Assert.Fail ("ThreadInterruptedException thrown twice");
816                                         }
817                                 }
818                         } catch (ThreadInterruptedException) {
819                                 interruptedExceptionThrown = true;
820                         }
821
822                         Assert.IsTrue (interruptedExceptionThrown, "ThreadInterruptedException expected.");
823                 }
824
825                 [Test]
826                 [ExpectedException (typeof (ArgumentNullException))]
827                 public void TestQueueUserWorkItemNullCallback ()
828                 {
829                         ThreadPool.QueueUserWorkItem (null, null);
830                 }
831
832                 private void Test_Interrupt_Worker (object o)
833                 {
834                         Thread t = o as Thread;
835                         Thread.Sleep (100);
836                         t.Interrupt ();
837                 }
838                 
839                 [Test]
840                 [Category ("NotDotNet")] // it crashes nunit.
841                 public void Test_InterruptCurrentThread ()
842                 {
843                         ManualResetEvent mre = new ManualResetEvent (false);
844                         bool interruptedExceptionThrown = false;
845
846                         Thread.CurrentThread.Interrupt ();
847                         try {
848                                 mre.WaitOne (0);
849                                 Assert.Fail ();
850                         } catch (ThreadInterruptedException) {
851                         }
852                 }
853
854                 [Test]
855                 public void GetNamedDataSlotTest ()
856                 {
857                         Assert.IsNotNull (Thread.GetNamedDataSlot ("te#st"), "#1");
858                         Assert.AreSame (Thread.GetNamedDataSlot ("te#st"), Thread.GetNamedDataSlot ("te#st"), "#2");
859                 }
860
861                 void CheckIsRunning (string s, Thread t)
862                 {
863                         int c = counter;
864                         Thread.Sleep (100);
865                         Assert.IsTrue (counter > c, s);
866                 }
867                 
868                 void CheckIsNotRunning (string s, Thread t)
869                 {
870                         int c = counter;
871                         Thread.Sleep (100);
872                         Assert.AreEqual (counter, c, s);
873                 }
874                 
875                 void WaitSuspended (string s, Thread t)
876                 {
877                         int n=0;
878                         ThreadState state = t.ThreadState;
879                         while ((state & ThreadState.Suspended) == 0) {
880                                 Assert.IsTrue ((state & ThreadState.SuspendRequested) != 0, s + ": expected SuspendRequested state");
881                                 Thread.Sleep (10);
882                                 n++;
883                                 Assert.IsTrue (n < 100, s + ": failed to suspend");
884                                 state = t.ThreadState;
885                         }
886                         Assert.IsTrue ((state & ThreadState.SuspendRequested) == 0, s + ": SuspendRequested state not expected");
887                 }
888                 
889                 void WaitResumed (string s, Thread t)
890                 {
891                         int n=0;
892                         while ((t.ThreadState & ThreadState.Suspended) != 0) {
893                                 Thread.Sleep (10);
894                                 n++;
895                                 Assert.IsTrue (n < 100, s + ": failed to resume");
896                         }
897                 }
898                 
899                 public void DoCount ()
900                 {
901                         while (true) {
902                                 counter++;
903                                 Thread.Sleep (1);
904                         }
905                 }
906         }
907
908         [TestFixture]
909         public class ThreadStateTest {
910                 void Start ()
911                 {
912                 }
913
914                 [Test] // bug #81720
915                 public void IsBackGround ()
916                 {
917                         Thread t1 = new Thread (new ThreadStart (Start));
918                         Assert.AreEqual (ThreadState.Unstarted, t1.ThreadState, "#A1");
919                         Assert.IsFalse (t1.IsBackground, "#A2");
920                         t1.Start ();
921                         t1.Join ();
922                         Assert.AreEqual (ThreadState.Stopped, t1.ThreadState, "#A3");
923
924                         try {
925                                 bool isBackGround = t1.IsBackground;
926                                 Assert.Fail ("#A4: " + isBackGround.ToString ());
927                         } catch (ThreadStateException ex) {
928                                 Assert.AreEqual (typeof (ThreadStateException), ex.GetType (), "#A5");
929                                 Assert.IsNull (ex.InnerException, "#A6");
930                                 Assert.IsNotNull (ex.Message, "#A7");
931                         }
932
933                         Thread t2 = new Thread (new ThreadStart (Start));
934                         Assert.AreEqual (ThreadState.Unstarted, t2.ThreadState, "#B1");
935                         t2.IsBackground = true;
936                         Assert.AreEqual (ThreadState.Unstarted | ThreadState.Background, t2.ThreadState, "#B2");
937                         Assert.IsTrue (t2.IsBackground, "#B3");
938                         t2.Start ();
939                         t2.Join ();
940                         Assert.AreEqual (ThreadState.Stopped, t2.ThreadState, "#B4");
941
942                         try {
943                                 bool isBackGround = t2.IsBackground;
944                                 Assert.Fail ("#B5: " + isBackGround.ToString ());
945                         } catch (ThreadStateException ex) {
946                                 Assert.AreEqual (typeof (ThreadStateException), ex.GetType (), "#B6");
947                                 Assert.IsNull (ex.InnerException, "#B7");
948                                 Assert.IsNotNull (ex.Message, "#B8");
949                         }
950                 }
951         }
952
953         [TestFixture]
954         [Serializable]
955         public class ThreadTest_ManagedThreadId
956         {
957                 AppDomain ad1;
958                 AppDomain ad2;
959                 MBRO mbro = new MBRO ();
960
961                 class MBRO : MarshalByRefObject {
962                         public int id_a1;
963                         public int id_b1;
964                         public int id_b2;
965                         public string ad_a1;
966                         public string ad_b1;
967                         public string ad_b2;
968                         public string message;
969                 }
970 #if !MOBILE
971                 [Test]
972                 public void ManagedThreadId_AppDomains ()
973                 {
974                         AppDomain currentDomain = AppDomain.CurrentDomain;
975                         ad1 = AppDomain.CreateDomain ("AppDomain 1", currentDomain.Evidence, currentDomain.SetupInformation);
976                         ad2 = AppDomain.CreateDomain ("AppDomain 2", currentDomain.Evidence, currentDomain.SetupInformation);
977
978                         Thread a = new Thread (ThreadA);
979                         Thread b = new Thread (ThreadB);
980                         // execute on AppDomain 1 thread A
981                         // execute on AppDomain 2 thread B
982                         // execute on AppDomain 1 thread B - must have same ManagedThreadId as Ad 2 on thread B
983                         a.Start ();
984                         a.Join ();
985                         b.Start ();
986                         b.Join ();
987
988                         AppDomain.Unload (ad1);
989                         AppDomain.Unload (ad2);
990
991                         if (mbro.message != null)
992                                 Assert.Fail (mbro.message);
993
994                         // 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);
995
996                         Assert.AreEqual ("AppDomain 1", mbro.ad_a1, "Name #1");
997                         Assert.AreEqual ("AppDomain 1", mbro.ad_b1, "Name #2");
998                         Assert.AreEqual ("AppDomain 2", mbro.ad_b2, "Name #3");
999
1000                         Assert.AreNotEqual (mbro.id_a1, mbro.id_b1, "Id #1");
1001                         Assert.AreNotEqual (mbro.id_a1, mbro.id_b2, "Id #2");
1002                         Assert.AreEqual (mbro.id_b1, mbro.id_b2, "Id #3");
1003
1004                         Assert.AreNotEqual (mbro.id_a1, Thread.CurrentThread.ManagedThreadId, "Id #4");
1005                         Assert.AreNotEqual (mbro.id_b1, Thread.CurrentThread.ManagedThreadId, "Id #5");
1006                         Assert.AreNotEqual (mbro.id_b2, Thread.CurrentThread.ManagedThreadId, "Id #6");
1007                         Assert.AreNotEqual (mbro.ad_a1, AppDomain.CurrentDomain.FriendlyName, "Name #4");
1008                         Assert.AreNotEqual (mbro.ad_b1, AppDomain.CurrentDomain.FriendlyName, "Name #5");
1009                         Assert.AreNotEqual (mbro.ad_b2, AppDomain.CurrentDomain.FriendlyName, "Name #6");
1010                 }
1011 #endif
1012                 void A1 ()
1013                 {
1014                         mbro.id_a1 = Thread.CurrentThread.ManagedThreadId;
1015                         mbro.ad_a1 = AppDomain.CurrentDomain.FriendlyName;
1016                 }
1017                 
1018                 void B2 ()
1019                 {
1020                         mbro.id_b2 = Thread.CurrentThread.ManagedThreadId;
1021                         mbro.ad_b2 = AppDomain.CurrentDomain.FriendlyName;
1022                 }
1023
1024                 void B1 ()
1025                 {
1026                         mbro.id_b1 = Thread.CurrentThread.ManagedThreadId;
1027                         mbro.ad_b1 = AppDomain.CurrentDomain.FriendlyName;
1028                 }
1029
1030                 void ThreadA (object obj)
1031                 {
1032                         // Console.WriteLine ("ThreadA");
1033                         try {
1034                                 ad1.DoCallBack (A1);
1035                         } catch (Exception ex) {
1036                                 mbro.message = string.Format ("ThreadA exception: {0}", ex);
1037                         }
1038                         // Console.WriteLine ("ThreadA Done");
1039                 }
1040
1041                 void ThreadB (object obj)
1042                 {
1043                         // Console.WriteLine ("ThreadB");
1044                         try {
1045                                 ad2.DoCallBack (B2);
1046                                 ad1.DoCallBack (B1);
1047                         } catch (Exception ex) {
1048                                 mbro.message = string.Format ("ThreadB exception: {0}", ex);
1049                         }
1050                         // Console.WriteLine ("ThreadB Done");
1051                 }
1052         }
1053
1054         [TestFixture]
1055         public class ThreadApartmentTest
1056         {
1057                 void Start ()
1058                 {
1059                 }
1060
1061                 [Test] // bug #81658
1062                 public void ApartmentState_StoppedThread ()
1063                 {
1064                         Thread t1 = new Thread (new ThreadStart (Start));
1065                         t1.Start ();
1066                         t1.Join ();
1067                         try {
1068                                 ApartmentState state = t1.ApartmentState;
1069                                 Assert.Fail ("#A1: " + state.ToString ());
1070                         } catch (ThreadStateException ex) {
1071                                 Assert.AreEqual (typeof (ThreadStateException), ex.GetType (), "#A2");
1072                                 Assert.IsNull (ex.InnerException, "#A3");
1073                                 Assert.IsNotNull (ex.Message, "#A4");
1074                         }
1075
1076                         Thread t2 = new Thread (new ThreadStart (Start));
1077                         t2.IsBackground = true;
1078                         t2.Start ();
1079                         t2.Join ();
1080                         try {
1081                                 ApartmentState state = t2.ApartmentState;
1082                                 Assert.Fail ("#B1: " + state.ToString ());
1083                         } catch (ThreadStateException ex) {
1084                                 Assert.AreEqual (typeof (ThreadStateException), ex.GetType (), "#B2");
1085                                 Assert.IsNull (ex.InnerException, "#B3");
1086                                 Assert.IsNotNull (ex.Message, "#B4");
1087                         }
1088                 }
1089
1090                 [Test]
1091                 public void ApartmentState_BackGround ()
1092                 {
1093                         Thread t1 = new Thread (new ThreadStart (Start));
1094                         t1.IsBackground = true;
1095                         Assert.AreEqual (ApartmentState.Unknown, t1.ApartmentState, "#1");
1096                         t1.ApartmentState = ApartmentState.STA;
1097                         Assert.AreEqual (ApartmentState.STA, t1.ApartmentState, "#2");
1098                 }
1099
1100                 [Test]
1101                 public void TestApartmentState ()
1102                 {
1103                         Thread t1 = new Thread (new ThreadStart (Start));
1104                         Thread t2 = new Thread (new ThreadStart (Start));
1105                         Thread t3 = new Thread (new ThreadStart (Start));
1106
1107                         Assert.AreEqual (ApartmentState.Unknown, t1.ApartmentState, "Thread1 Default");
1108                         Assert.AreEqual (ApartmentState.Unknown, t2.ApartmentState, "Thread2 Default");
1109                         Assert.AreEqual (ApartmentState.Unknown, t3.ApartmentState, "Thread3 Default");
1110
1111                         t1.ApartmentState = ApartmentState.STA;
1112                         Assert.AreEqual (ApartmentState.STA, t1.ApartmentState, "Thread1 Set Once");
1113                         t1.ApartmentState = ApartmentState.MTA;
1114                         Assert.AreEqual (ApartmentState.STA, t1.ApartmentState, "Thread1 Set Twice");
1115
1116                         t2.ApartmentState = ApartmentState.MTA;
1117                         Assert.AreEqual (ApartmentState.MTA, t2.ApartmentState, "Thread2 Set Once");
1118                         t2.ApartmentState = ApartmentState.STA;
1119                         Assert.AreEqual (ApartmentState.MTA, t2.ApartmentState, "Thread2 Set Twice");
1120
1121                         bool exception_occured = false;
1122                         try {
1123                                 t3.ApartmentState = ApartmentState.Unknown;
1124                         }
1125                         catch (Exception) {
1126                                 exception_occured = true;
1127                         }
1128                         Assert.AreEqual (ApartmentState.Unknown, t3.ApartmentState, "Thread3 Set Invalid");
1129                         Assert.IsFalse (exception_occured, "Thread3 Set Invalid Exception Occured");
1130
1131                         t1.Start ();
1132                         exception_occured = false;
1133                         try {
1134                                 t1.ApartmentState = ApartmentState.STA;
1135                         }
1136                         catch (Exception) {
1137                                 exception_occured = true;
1138                         }
1139                         Assert.IsTrue (exception_occured, "Thread1 Started Invalid Exception Occured");
1140                 }
1141
1142                 [Test]
1143                 public void TestSetApartmentStateSameState ()
1144                 {
1145                         Thread t1 = new Thread (new ThreadStart (Start));
1146                         t1.SetApartmentState (ApartmentState.STA);
1147                         Assert.AreEqual (ApartmentState.STA, t1.ApartmentState, "Thread1 Set Once");
1148
1149                         t1.SetApartmentState (ApartmentState.STA);
1150                         Assert.AreEqual (ApartmentState.STA, t1.ApartmentState, "Thread1 Set twice");
1151                 }
1152
1153                 [Test]
1154                 [ExpectedException(typeof(InvalidOperationException))]
1155                 public void TestSetApartmentStateDiffState ()
1156                 {
1157                         Thread t1 = new Thread (new ThreadStart (Start));
1158                         t1.SetApartmentState (ApartmentState.STA);
1159                         Assert.AreEqual (ApartmentState.STA, t1.ApartmentState, "Thread1 Set Once");
1160
1161                         t1.SetApartmentState (ApartmentState.MTA);
1162                 }
1163
1164                 [Test]
1165                 public void TestTrySetApartmentState ()
1166                 {
1167                         Thread t1 = new Thread (new ThreadStart (Start));
1168                         t1.SetApartmentState (ApartmentState.STA);
1169                         Assert.AreEqual (ApartmentState.STA, t1.ApartmentState, "#1");
1170
1171                         bool result = t1.TrySetApartmentState (ApartmentState.MTA);
1172                         Assert.IsFalse (result, "#2");
1173
1174                         result = t1.TrySetApartmentState (ApartmentState.STA);
1175                         Assert.IsTrue (result, "#3");
1176                 }
1177
1178                 [Test]
1179                 public void TestTrySetApartmentStateRunning ()
1180                 {
1181                         Thread t1 = new Thread (new ThreadStart (Start));
1182                         t1.SetApartmentState (ApartmentState.STA);
1183                         Assert.AreEqual (ApartmentState.STA, t1.ApartmentState, "#1");
1184
1185                         t1.Start ();
1186
1187                         try {
1188                                 t1.TrySetApartmentState (ApartmentState.STA);
1189                                 Assert.Fail ("#2");
1190                         } catch (ThreadStateException) {
1191                         }
1192
1193                         t1.Join ();
1194                 }
1195
1196                 [Test]
1197                 public void Volatile () {
1198                         double v3 = 55667;
1199                         Thread.VolatileWrite (ref v3, double.MaxValue);
1200                         Assert.AreEqual (v3, double.MaxValue);
1201
1202                         float v4 = 1;
1203                         Thread.VolatileWrite (ref v4, float.MaxValue);
1204                         Assert.AreEqual (v4, float.MaxValue);
1205                 }
1206
1207                 [Test]
1208                 public void Culture ()
1209                 {
1210                         Assert.IsNotNull (Thread.CurrentThread.CurrentCulture, "CurrentCulture");
1211                         Assert.IsNotNull (Thread.CurrentThread.CurrentUICulture, "CurrentUICulture");
1212                 }
1213
1214                 [Test]
1215                 public void ThreadStartSimple ()
1216                 {
1217                         int i = 0;
1218                         Thread t = new Thread (delegate () {
1219                                 // ensure the NSAutoreleasePool works
1220                                 i++;
1221                         });
1222                         t.Start ();
1223                         t.Join ();
1224                         Assert.AreEqual (1, i, "ThreadStart");
1225                 }
1226
1227                 [Test]
1228                 public void ParametrizedThreadStart ()
1229                 {
1230                         int i = 0;
1231                         object arg = null;
1232                         Thread t = new Thread (delegate (object obj) {
1233                                 // ensure the NSAutoreleasePool works
1234                                 i++;
1235                                 arg = obj;
1236                         });
1237                         t.Start (this);
1238                         t.Join ();
1239
1240                         Assert.AreEqual (1, i, "ParametrizedThreadStart");
1241                         Assert.AreEqual (this, arg, "obj");     
1242                 }               
1243
1244                 [Test]
1245                 public void SetNameTpThread () {
1246                         ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc));
1247                 }
1248
1249                 static void ThreadProc(Object stateInfo) {
1250                         Thread.CurrentThread.Name = "My Worker";
1251                 }
1252         }
1253
1254         public class TestUtil
1255         {
1256                 public static void WaitForNotAlive (Thread t, string s)
1257                 {
1258                         WhileAlive (t, true, s);
1259                 }
1260                 
1261                 public static void WaitForAlive (Thread t, string s)
1262                 {
1263                         WhileAlive (t, false, s);
1264                 }
1265                 
1266                 public static bool WaitForAliveOrStop (Thread t, string s)
1267                 {
1268                         return WhileAliveOrStop (t, false, s);
1269                 }
1270                 
1271                 public static void WhileAlive (Thread t, bool alive, string s)
1272                 {
1273                         DateTime ti = DateTime.Now;
1274                         while (t.IsAlive == alive) {
1275                                 if ((DateTime.Now - ti).TotalSeconds > 10) {
1276                                         if (alive) Assert.Fail ("Timeout while waiting for not alive state. " + s);
1277                                         else Assert.Fail ("Timeout while waiting for alive state. " + s);
1278                                 }
1279                         }
1280                 }
1281
1282                 public static bool WhileAliveOrStop (Thread t, bool alive, string s)
1283                 {
1284                         DateTime ti = DateTime.Now;
1285                         while (t.IsAlive == alive) {
1286                                 if (t.ThreadState == ThreadState.Stopped)
1287                                         return false;
1288
1289                                 if ((DateTime.Now - ti).TotalSeconds > 10) {
1290                                         if (alive) Assert.Fail ("Timeout while waiting for not alive state. " + s);
1291                                         else Assert.Fail ("Timeout while waiting for alive state. " + s);
1292                                 }
1293                         }
1294
1295                         return true;
1296                 }
1297         }
1298 }