Merge pull request #4998 from kumpera/fix_56684
[mono.git] / mono / tests / static-constructor.cs
1
2 using System;
3 using System.Reflection;
4 using System.Threading;
5
6 struct A {
7         public A (int i) {
8         }
9 }
10
11 struct B {
12         public B (int i) {
13         }
14 }
15
16 public class StaticInitFails {
17
18         public static string s;
19
20         static StaticInitFails () {
21                 Thread.Sleep (1000);
22                 throw new Exception ();
23                 s = "FOO";
24         }
25
26         public static void foo () {
27                 Console.WriteLine (s);
28         }
29 }
30
31 public class Tests {
32         static int last = 42;
33         static int burp;
34
35         static Tests () {
36                 /* 
37                  * This is really at test of the compiler: it should init
38                  * last before getting here.
39                 */
40                 if (last != 42)
41                         burp = 5;
42                 else
43                         burp = 4;
44         }
45         public static int Main() {
46                 if (last != 42)
47                         return 1;
48                 if (burp != 4)
49                         return 1;
50
51                 // Regression test for bug #59193 (shared runtime wrappers)
52                 ConstructorInfo con1 = typeof (A).GetConstructor (BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type [1] { typeof (int) }, null);
53                 ConstructorInfo con2 = typeof (B).GetConstructor (BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type [1] { typeof (int) }, null);
54
55                 con1.Invoke (new Object [] { 0 });
56                 con2.Invoke (new Object [] { 0 });
57
58                 // Test what happens when static initialization throws an exception
59                 // First start a thread which will trigger the initialization
60                 Thread t = new Thread (new ThreadStart (Run));
61                 t.Start ();
62
63                 Thread.Sleep (500);
64
65                 // While the thread waits, trigger initialization on this thread too so this
66                 // thread will wait for the other thread to finish initialization
67                 try {
68                         Run2 ();
69                         return 1;
70                 }
71                 catch (TypeInitializationException ex) {
72                 }
73
74                 // Try again synchronously
75                 try {
76                         Run2 ();
77                         return 1;
78                 }
79                 catch (TypeInitializationException ex) {
80                 }
81
82                 return 0;
83         }
84
85         private static void Run () {
86                 try {
87                         StaticInitFails.foo ();
88                 }
89                 catch (Exception) {
90                 }
91         }
92
93         private static void Run2 () {
94                 StaticInitFails.foo ();
95         }
96
97 }