2 using System
.Diagnostics
;
3 using System
.Threading
;
4 using System
.Runtime
.CompilerServices
;
8 public static ManualResetEvent mre1
= new ManualResetEvent (false);
9 public static ManualResetEvent mre2
= new ManualResetEvent (false);
11 class StaticConstructor1
13 internal static bool gotToEnd
, caughtException
;
14 static StaticConstructor1 ()
17 Console
.WriteLine ("StaticConstructor1.StaticConstructor1 (1)");
19 var sw
= Stopwatch
.StartNew ();
22 typeof (string).GetMethods ();
23 //XXX we assume that if we slept less than 900ms we got aborted
24 if (sw
.ElapsedMilliseconds
< 900)
25 throw new Exception ("Bad abort broke our sleep");
26 Console
.WriteLine ("StaticConstructor1.StaticConstructor1 (2) waited {0}", sw
.ElapsedMilliseconds
);
28 } catch (Exception e
) {
29 caughtException
= true;
34 public static void Init ()
36 Console
.WriteLine ("StaticConstructor1.Init");
40 [MethodImplAttribute (MethodImplOptions
.NoInlining
)]
41 static void IsStaticConstructor1Viable () {
42 new StaticConstructor1 ();
43 Console
.WriteLine ("Did it get to the end? {0} Did it catch an exception {1}", StaticConstructor1
.gotToEnd
, StaticConstructor1
.caughtException
);
44 if (!StaticConstructor1
.gotToEnd
) /* the TAE must not land during a .cctor */
46 if (StaticConstructor1
.caughtException
)
53 Console
.WriteLine ("Test 1:");
58 Thread thread
= new Thread (() => {
60 StaticConstructor1
.Init ();
61 } catch (Exception e
) {
62 Console
.WriteLine ("StaticConstructor1::init caught exception {0}", e
);
64 if (!(e
is ThreadAbortException
))
71 Driver
.mre1
.WaitOne ();
73 // The ThreadAbortException should land while in
74 // the StaticConstructor1.cctor. The exception should
75 // be queued, and be rethrown when exiting the cctor.
80 //is StaticConstructor1 viable?
82 IsStaticConstructor1Viable ();
83 Console
.WriteLine ("StaticConstructor1 is viable"); /* a TAE doesn't make a type unusable */
84 } catch (TypeInitializationException e
) {
85 Console
.WriteLine ("StaticConstructor1 not viable");
90 class StaticConstructor2Exception
: Exception
{}
92 class StaticConstructor2
94 static StaticConstructor2 ()
96 Console
.WriteLine ("StaticConstructor2.StaticConstructor2 (1)");
98 throw new StaticConstructor2Exception ();
101 Console
.WriteLine ("StaticConstructor2.StaticConstructor2 (2)");
104 public static void Init ()
106 Console
.WriteLine ("StaticConstructor2.Init");
110 [MethodImplAttribute (MethodImplOptions
.NoInlining
)]
111 static void IsStaticConstructor2Viable () {
112 new StaticConstructor2 ();
118 Console
.WriteLine ("Test 2:");
120 Driver
.mre1
.Reset ();
121 Driver
.mre2
.Reset ();
123 Thread thread
= new Thread (() => {
125 StaticConstructor2
.Init ();
126 } catch (TypeInitializationException e
) {
127 Console
.WriteLine (e
);
129 if (!(e
.InnerException
is StaticConstructor2Exception
))
136 Driver
.mre1
.WaitOne ();
138 // A InvalidOperationException should be thrown while in
139 // the StaticConstructor2.cctor. The exception should
140 // be wrapped in a TypeInitializationException.
142 if (Driver
.mre2
.WaitOne (500)) {
143 /* We shouldn't reach Driver.mre.Set () in StaticConstructor2.cctor */
144 Environment
.Exit (1);
149 //is StaticConstructor2 viable?
151 IsStaticConstructor2Viable ();
152 Console
.WriteLine ("StaticConstructor2 is viable");
153 /* A regular exception escaping the .cctor makes the type not usable */
154 Environment
.Exit (1);
155 } catch (TypeInitializationException e
) {
156 Console
.WriteLine ("StaticConstructor2 not viable");
161 class StaticConstructor3
163 static StaticConstructor3 ()
165 Console
.WriteLine ("StaticConstructor3.StaticConstructor3 (1)");
167 Thread
.CurrentThread
.Abort ();
170 Console
.WriteLine ("StaticConstructor3.StaticConstructor3 (2)");
171 Environment
.Exit (1);
174 public static void Init ()
176 Console
.WriteLine ("StaticConstructor3.Init");
180 [MethodImplAttribute (MethodImplOptions
.NoInlining
)]
181 static void IsStaticConstructor3Viable () {
182 new StaticConstructor3 ();
187 Console
.WriteLine ("Test 3:");
189 Driver
.mre1
.Reset ();
190 Driver
.mre2
.Reset ();
192 Thread thread
= new Thread (() => {
194 StaticConstructor3
.Init ();
195 Console
.WriteLine ("cctor3 didn't throw?!?!");
196 /* StaticConstructor3 self aborted */
197 Environment
.Exit (1);
198 } catch (ThreadAbortException e
) {
199 Console
.WriteLine ("TEST 3: aborted {0}", e
);
205 Driver
.mre1
.WaitOne ();
207 // A InvalidOperationException should be thrown while in
208 // the StaticConstructor2.cctor. The exception should
209 // be wrapped in a TypeInitializationException.
213 //is StaticConstructor2 viable?
215 IsStaticConstructor3Viable ();
216 Console
.WriteLine ("StaticConstructor3 is viable");
217 /* A regular exception escaping the .cctor makes the type not usable */
218 Environment
.Exit (1);
219 } catch (TypeInitializationException e
) {
220 Console
.WriteLine ("StaticConstructor3 not viable");
228 class StaticConstructor4
230 internal static bool gotToEnd
, caughtException
;
232 static StaticConstructor4 ()
235 Console
.WriteLine ("StaticConstructor4.StaticConstructor4 (1)");
237 var sw
= Stopwatch
.StartNew ();
240 typeof (string).GetMethods ();
241 //XXX we assume that if we slept less than 900ms we got aborted
242 if (sw
.ElapsedMilliseconds
< 900)
243 throw new Exception ("Bad abort broke our sleep");
244 Console
.WriteLine ("StaticConstructor4.StaticConstructor4 (2) waited {0}", sw
.ElapsedMilliseconds
);
246 } catch (Exception e
) {
247 caughtException
= true;
252 public static void Init ()
254 Console
.WriteLine ("StaticConstructor4.Init");
258 static bool got_to_the_end_of_the_finally
= false;
260 [MethodImplAttribute (MethodImplOptions
.NoInlining
)]
261 static void IsStaticConstructor4Viable () {
262 new StaticConstructor4 ();
263 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
);
264 if (!StaticConstructor4
.gotToEnd
) /* the TAE must not land during a .cctor */
265 Environment
.Exit (1);
266 if (StaticConstructor4
.caughtException
)
267 Environment
.Exit (1);
272 Console
.WriteLine ("Test 4:");
274 Driver
.mre1
.Reset ();
275 Driver
.mre2
.Reset ();
277 Thread thread
= new Thread (() => {
282 StaticConstructor4
.Init ();
283 Console
.WriteLine ("Test 4: After the cctor");
284 got_to_the_end_of_the_finally
= true;
286 } catch (Exception e
) {
287 Console
.WriteLine ("StaticConstructor4::init caught exception {0}", e
);
288 if (!(e
is ThreadAbortException
))
290 if (!got_to_the_end_of_the_finally
)
291 throw new Exception ("Test 4: did not get to the end of the cctor");
297 Driver
.mre1
.WaitOne ();
299 // The ThreadAbortException should land while in
300 // the StaticConstructor4.cctor. The exception should
301 // be queued, and be rethrown when exiting the cctor.
306 if (!got_to_the_end_of_the_finally
) {
307 Console
.WriteLine ("Did not get to the end of test 4 cctor");
308 Environment
.Exit (1);
311 //is StaticConstructor4viable?
313 IsStaticConstructor4Viable ();
314 Console
.WriteLine ("StaticConstructor4 is viable"); /* a TAE doesn't make a type unusable */
315 } catch (TypeInitializationException e
) {
316 Console
.WriteLine ("StaticConstructor4 not viable");
317 Environment
.Exit (1);
323 public static int Main ()
329 Console
.WriteLine ("done, all things good");