2 using System
.Diagnostics
;
3 using System
.Threading
;
4 using System
.Runtime
.CompilerServices
;
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 ()
18 Console
.WriteLine ("StaticConstructor1.StaticConstructor1 (1)");
20 var sw
= Stopwatch
.StartNew ();
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
);
29 } catch (Exception e
) {
30 caughtException
= true;
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 */
47 if (StaticConstructor1
.caughtException
)
54 Console
.WriteLine ("Test 1:");
59 Thread thread
= new Thread (() => {
61 StaticConstructor1
.Init ();
62 } catch (Exception e
) {
63 Console
.WriteLine ("StaticConstructor1::init caught exception {0}", e
);
65 if (!(e
is ThreadAbortException
))
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.
81 //is StaticConstructor1 viable?
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");
91 class StaticConstructor2Exception
: Exception
{}
93 class StaticConstructor2
95 static StaticConstructor2 ()
97 Console
.WriteLine ("StaticConstructor2.StaticConstructor2 (1)");
99 throw new StaticConstructor2Exception ();
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 ();
119 Console
.WriteLine ("Test 2:");
121 Driver
.mre1
.Reset ();
122 Driver
.mre2
.Reset ();
124 Thread thread
= new Thread (() => {
126 StaticConstructor2
.Init ();
127 } catch (TypeInitializationException e
) {
128 Console
.WriteLine (e
);
130 if (!(e
.InnerException
is StaticConstructor2Exception
))
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);
150 //is StaticConstructor2 viable?
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)");
168 Thread
.CurrentThread
.Abort ();
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 ();
188 Console
.WriteLine ("Test 3:");
189 bool catched_abort
= false;
191 Driver
.mre1
.Reset ();
192 Driver
.mre2
.Reset ();
194 Thread thread
= new Thread (() => {
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;
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.
216 // Did we catch the abort
218 Environment
.Exit (8);
220 //is StaticConstructor2 viable?
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 ()
242 Console
.WriteLine ("StaticConstructor4.StaticConstructor4 (1)");
244 var sw
= Stopwatch
.StartNew ();
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
);
253 } catch (Exception e
) {
254 caughtException
= true;
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);
279 Console
.WriteLine ("Test 4:");
281 Driver
.mre1
.Reset ();
282 Driver
.mre2
.Reset ();
284 Thread thread
= new Thread (() => {
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
))
297 if (!got_to_the_end_of_the_finally
)
298 throw new Exception ("Test 4: did not get to the end of the cctor");
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.
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?
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 ()
334 Driver
.mre2
.WaitOne ();
336 throw new Exception ();
337 } catch (Exception
) {
338 Console
.WriteLine ("Catched exception in cctor");
339 catched_exception
= true;
346 bool catched_abort
= false;
347 Driver
.mre1
.Reset ();
348 Driver
.mre2
.Reset ();
349 Thread thread
= new Thread (() => {
351 new StaticConstructor5 ();
352 } catch (ThreadAbortException
) {
353 Console
.WriteLine ("Catched thread abort");
354 catched_abort
= true;
359 Driver
.mre1
.WaitOne ();
365 if (!StaticConstructor5
.catched_exception
)
366 Environment
.Exit (14);
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 ()
381 Driver
.got_to_the_end_of_outer_finally
= true;
385 [MethodImplAttribute (MethodImplOptions
.NoInlining
)]
386 public static void Setup6 () {
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 ();
415 Driver
.sema1
.Wait ();
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 ()
435 Console
.WriteLine ("done, all things good");