Reduce TLS accesses. (#11487)
[mono-project.git] / mono / tests / abort-cctor.cs
blobd4551e03493867d75470f2e080eec2fb2d92cc69
1 using System;
2 using System.Diagnostics;
3 using System.Threading;
4 using System.Runtime.CompilerServices;
6 class Driver
8 public static SemaphoreSlim sema1 = new SemaphoreSlim (0);
9 public static ManualResetEvent mre1 = new ManualResetEvent (false);
10 public static ManualResetEvent mre2 = new ManualResetEvent (false);
12 class StaticConstructor1
14 internal static bool gotToEnd, caughtException;
15 static StaticConstructor1 ()
17 try {
18 Console.WriteLine ("StaticConstructor1.StaticConstructor1 (1)");
19 Driver.mre1.Set ();
20 var sw = Stopwatch.StartNew ();
21 Thread.Sleep (1000);
22 sw.Stop ();
23 typeof (string).GetMethods ();
24 //XXX we assume that if we slept less than 900ms we got aborted
25 if (sw.ElapsedMilliseconds < 900)
26 throw new Exception ("Bad abort broke our sleep");
27 Console.WriteLine ("StaticConstructor1.StaticConstructor1 (2) waited {0}", sw.ElapsedMilliseconds);
28 gotToEnd = true;
29 } catch (Exception e) {
30 caughtException = true;
31 throw;
35 public static void Init ()
37 Console.WriteLine ("StaticConstructor1.Init");
41 [MethodImplAttribute (MethodImplOptions.NoInlining)]
42 static void IsStaticConstructor1Viable () {
43 new StaticConstructor1 ();
44 Console.WriteLine ("Did it get to the end? {0} Did it catch an exception {1}", StaticConstructor1.gotToEnd, StaticConstructor1.caughtException);
45 if (!StaticConstructor1.gotToEnd) /* the TAE must not land during a .cctor */
46 Environment.Exit (1);
47 if (StaticConstructor1.caughtException)
48 Environment.Exit (2);
52 static void Test1 ()
54 Console.WriteLine ("Test 1:");
56 Driver.mre1.Reset ();
57 Driver.mre2.Reset ();
59 Thread thread = new Thread (() => {
60 try {
61 StaticConstructor1.Init ();
62 } catch (Exception e) {
63 Console.WriteLine ("StaticConstructor1::init caught exception {0}", e);
65 if (!(e is ThreadAbortException))
66 throw;
68 });
70 thread.Start ();
72 Driver.mre1.WaitOne ();
74 // The ThreadAbortException should land while in
75 // the StaticConstructor1.cctor. The exception should
76 // be queued, and be rethrown when exiting the cctor.
77 thread.Abort ();
79 thread.Join ();
81 //is StaticConstructor1 viable?
82 try {
83 IsStaticConstructor1Viable ();
84 Console.WriteLine ("StaticConstructor1 is viable"); /* a TAE doesn't make a type unusable */
85 } catch (TypeInitializationException e) {
86 Console.WriteLine ("StaticConstructor1 not viable");
87 Environment.Exit (3);
91 class StaticConstructor2Exception : Exception {}
93 class StaticConstructor2
95 static StaticConstructor2 ()
97 Console.WriteLine ("StaticConstructor2.StaticConstructor2 (1)");
98 Driver.mre1.Set ();
99 throw new StaticConstructor2Exception ();
100 /* Unreachable */
101 Driver.mre2.Set ();
102 Console.WriteLine ("StaticConstructor2.StaticConstructor2 (2)");
105 public static void Init ()
107 Console.WriteLine ("StaticConstructor2.Init");
111 [MethodImplAttribute (MethodImplOptions.NoInlining)]
112 static void IsStaticConstructor2Viable () {
113 new StaticConstructor2 ();
117 static void Test2 ()
119 Console.WriteLine ("Test 2:");
121 Driver.mre1.Reset ();
122 Driver.mre2.Reset ();
124 Thread thread = new Thread (() => {
125 try {
126 StaticConstructor2.Init ();
127 } catch (TypeInitializationException e) {
128 Console.WriteLine (e);
130 if (!(e.InnerException is StaticConstructor2Exception))
131 throw;
135 thread.Start ();
137 Driver.mre1.WaitOne ();
139 // A InvalidOperationException should be thrown while in
140 // the StaticConstructor2.cctor. The exception should
141 // be wrapped in a TypeInitializationException.
143 if (Driver.mre2.WaitOne (500)) {
144 /* We shouldn't reach Driver.mre.Set () in StaticConstructor2.cctor */
145 Environment.Exit (4);
148 thread.Join ();
150 //is StaticConstructor2 viable?
151 try {
152 IsStaticConstructor2Viable ();
153 Console.WriteLine ("StaticConstructor2 is viable");
154 /* A regular exception escaping the .cctor makes the type not usable */
155 Environment.Exit (5);
156 } catch (TypeInitializationException e) {
157 Console.WriteLine ("StaticConstructor2 not viable");
162 class StaticConstructor3
164 static StaticConstructor3 ()
166 Console.WriteLine ("StaticConstructor3.StaticConstructor3 (1)");
167 Driver.mre1.Set ();
168 Thread.CurrentThread.Abort ();
169 /* Unreachable */
170 Driver.mre2.Set ();
171 Console.WriteLine ("StaticConstructor3.StaticConstructor3 (2)");
172 Environment.Exit (6);
175 public static void Init ()
177 Console.WriteLine ("StaticConstructor3.Init");
181 [MethodImplAttribute (MethodImplOptions.NoInlining)]
182 static void IsStaticConstructor3Viable () {
183 new StaticConstructor3 ();
186 static void Test3 ()
188 Console.WriteLine ("Test 3:");
189 bool catched_abort = false;
191 Driver.mre1.Reset ();
192 Driver.mre2.Reset ();
194 Thread thread = new Thread (() => {
195 try {
196 StaticConstructor3.Init ();
197 Console.WriteLine ("cctor3 didn't throw?!?!");
198 /* StaticConstructor3 self aborted */
199 Environment.Exit (7);
200 } catch (ThreadAbortException e) {
201 Console.WriteLine ("TEST 3: aborted {0}", e);
202 catched_abort = true;
206 thread.Start ();
208 Driver.mre1.WaitOne ();
210 // A InvalidOperationException should be thrown while in
211 // the StaticConstructor2.cctor. The exception should
212 // be wrapped in a TypeInitializationException.
214 thread.Join ();
216 // Did we catch the abort
217 if (!catched_abort)
218 Environment.Exit (8);
220 //is StaticConstructor2 viable?
221 try {
222 IsStaticConstructor3Viable ();
223 Console.WriteLine ("StaticConstructor3 is viable");
224 /* A regular exception escaping the .cctor makes the type not usable */
225 Environment.Exit (9);
226 } catch (TypeInitializationException e) {
227 Console.WriteLine ("StaticConstructor3 not viable");
235 class StaticConstructor4
237 internal static bool gotToEnd, caughtException;
239 static StaticConstructor4 ()
241 try {
242 Console.WriteLine ("StaticConstructor4.StaticConstructor4 (1)");
243 Driver.mre1.Set ();
244 var sw = Stopwatch.StartNew ();
245 Thread.Sleep (1000);
246 sw.Stop ();
247 typeof (string).GetMethods ();
248 //XXX we assume that if we slept less than 900ms we got aborted
249 if (sw.ElapsedMilliseconds < 900)
250 throw new Exception ("Bad abort broke our sleep");
251 Console.WriteLine ("StaticConstructor4.StaticConstructor4 (2) waited {0}", sw.ElapsedMilliseconds);
252 gotToEnd = true;
253 } catch (Exception e) {
254 caughtException = true;
255 throw;
259 public static void Init ()
261 Console.WriteLine ("StaticConstructor4.Init");
265 static bool got_to_the_end_of_the_finally = false;
267 [MethodImplAttribute (MethodImplOptions.NoInlining)]
268 static void IsStaticConstructor4Viable () {
269 new StaticConstructor4 ();
270 Console.WriteLine ("IsStaticConstructor4Viable: Did it get to the end? {0} Did it catch an exception {1} and end of the finally block {2}", StaticConstructor4.gotToEnd, StaticConstructor4.caughtException, got_to_the_end_of_the_finally);
271 if (!StaticConstructor4.gotToEnd) /* the TAE must not land during a .cctor */
272 Environment.Exit (10);
273 if (StaticConstructor4.caughtException)
274 Environment.Exit (11);
277 static void Test4 ()
279 Console.WriteLine ("Test 4:");
281 Driver.mre1.Reset ();
282 Driver.mre2.Reset ();
284 Thread thread = new Thread (() => {
285 try {
287 try {
288 } finally {
289 StaticConstructor4.Init ();
290 Console.WriteLine ("Test 4: After the cctor");
291 got_to_the_end_of_the_finally = true;
293 } catch (Exception e) {
294 Console.WriteLine ("StaticConstructor4::init caught exception {0}", e);
295 if (!(e is ThreadAbortException))
296 throw;
297 if (!got_to_the_end_of_the_finally)
298 throw new Exception ("Test 4: did not get to the end of the cctor");
302 thread.Start ();
304 Driver.mre1.WaitOne ();
306 // The ThreadAbortException should land while in
307 // the StaticConstructor4.cctor. The exception should
308 // be queued, and be rethrown when exiting the cctor.
309 thread.Abort ();
311 thread.Join ();
313 if (!got_to_the_end_of_the_finally) {
314 Console.WriteLine ("Did not get to the end of test 4 cctor");
315 Environment.Exit (12);
318 //is StaticConstructor4viable?
319 try {
320 IsStaticConstructor4Viable ();
321 Console.WriteLine ("StaticConstructor4 is viable"); /* a TAE doesn't make a type unusable */
322 } catch (TypeInitializationException e) {
323 Console.WriteLine ("StaticConstructor4 not viable");
324 Environment.Exit (13);
329 class StaticConstructor5 {
330 public static bool catched_exception = false;
331 static StaticConstructor5 ()
333 Driver.mre1.Set ();
334 Driver.mre2.WaitOne ();
335 try {
336 throw new Exception ();
337 } catch (Exception) {
338 Console.WriteLine ("Catched exception in cctor");
339 catched_exception = true;
344 static void Test5 ()
346 bool catched_abort = false;
347 Driver.mre1.Reset ();
348 Driver.mre2.Reset ();
349 Thread thread = new Thread (() => {
350 try {
351 new StaticConstructor5 ();
352 } catch (ThreadAbortException) {
353 Console.WriteLine ("Catched thread abort");
354 catched_abort = true;
357 thread.Start ();
359 Driver.mre1.WaitOne ();
360 thread.Abort ();
361 Driver.mre2.Set ();
363 thread.Join ();
365 if (!StaticConstructor5.catched_exception)
366 Environment.Exit (14);
367 if (!catched_abort)
368 Environment.Exit (15);
371 public static bool got_to_the_end_of_outer_finally = false;
372 public static bool got_to_the_end_of_inner_finally = false;
374 class StaticConstructor6 {
376 static StaticConstructor6 ()
378 try {
379 Setup6 ();
380 } finally {
381 Driver.got_to_the_end_of_outer_finally = true;
385 [MethodImplAttribute (MethodImplOptions.NoInlining)]
386 public static void Setup6 () {
387 try {
388 } finally {
389 Driver.sema1.Release ();
390 Thread.Sleep (1000); /* hopefully we get woken up here */
391 Driver.got_to_the_end_of_inner_finally = true;
396 [MethodImplAttribute (MethodImplOptions.NoInlining)]
397 static void IsStaticConstructor6Viable () {
398 Console.WriteLine ("IsStaticConstructor6Viable? got to inner finally? {0} got to outer finally? {1}",
399 Driver.got_to_the_end_of_inner_finally,
400 Driver.got_to_the_end_of_outer_finally);
401 new StaticConstructor6 ();
402 if (!Driver.got_to_the_end_of_inner_finally)
403 Environment.Exit (17);
404 if (!Driver.got_to_the_end_of_outer_finally)
405 Environment.Exit (18);
408 public static void Test6 ()
410 Thread thread = new Thread (() => {
411 new StaticConstructor6 ();
414 thread.Start ();
415 Driver.sema1.Wait ();
416 thread.Abort ();
417 thread.Join ();
418 try {
419 IsStaticConstructor6Viable ();
420 Console.WriteLine ("StaticConstructor6 is viable");
421 } catch (TypeInitializationException e) {
422 Console.WriteLine ("StaticConstructor6 is not viable");
423 Environment.Exit (19);
427 public static int Main ()
429 Test1 ();
430 Test2 ();
431 Test3 ();
432 Test4 ();
433 Test5 ();
434 Test6 ();
435 Console.WriteLine ("done, all things good");
436 return 0;