Merge pull request #5390 from kumpera/fix_58637
[mono.git] / mono / tests / finally_guard.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Reflection;
4 using System.Threading;
5 using System.Runtime.CompilerServices;
6
7
8 class Driver {
9         static int result;
10         static bool finally_done;
11         static ManualResetEvent handle;
12         static Thread thread;
13         static object broken;
14
15         [MethodImplAttribute (MethodImplOptions.NoInlining)]
16         static void ThrowE () {
17                 broken.ToString ();             
18         }
19
20         static bool InterruptRequested () {
21                 return (Thread.CurrentThread.ThreadState & ThreadState.AbortRequested) == ThreadState.AbortRequested;
22         }
23
24         [MethodImplAttribute (MethodImplOptions.NoInlining)]
25         public static void SleepLoop () {
26                 for (int i = 0; i < 10; ++i) {
27                         Console.WriteLine ("step {0} - {1}", i, Thread.CurrentThread.ThreadState);
28                         if (InterruptRequested ())
29                                 break;
30                         Thread.Sleep (100);
31                 }
32
33                 if (!InterruptRequested ())
34                         result |= 0x1;
35
36                 try {
37                         ThrowE ();
38                 } catch (Exception e) {
39                         Console.WriteLine ("caught/0 {0} from inside the prot block", e.GetType ());
40                         if (!(e is NullReferenceException))
41                                 result |= 0x2;
42                 }
43         }
44
45         [MethodImplAttribute (MethodImplOptions.NoInlining)]
46         public static void CancelAbort () {
47                 object lk = new object ();
48                 Console.WriteLine ("step 0 - {0}", Thread.CurrentThread.ThreadState);
49                 //lock (lk) { Monitor.Wait (lk, 100); }
50                 Console.WriteLine ("step 1 - {0}", Thread.CurrentThread.ThreadState);
51                 Thread.ResetAbort ();
52         }
53
54         /////////////////////////////////////////////////////
55         [MethodImplAttribute (MethodImplOptions.NoInlining)]
56         static void InnerFromEH0 () {
57                 thread = Thread.CurrentThread;
58                 MethodInfo mi = typeof (Driver).GetMethod ("SleepLoop");
59                 try {
60                         try {
61                                 throw new ArgumentException ();
62                         } finally {     
63                                 handle.Set ();
64                                 SleepLoop ();
65                                 Console.WriteLine ("done");
66                                 finally_done = true;
67                         }
68                         Console.WriteLine ("After finally");
69                         result |= 0x10;
70                 } catch (Exception e) {
71                         if (!(e is ArgumentException))
72                                 result |= 0x4;
73                         Console.WriteLine ("caught/1 a {0} while on {1} res {2}", e.GetType (), Thread.CurrentThread.ThreadState, result);
74                 }
75         }
76
77         [MethodImplAttribute (MethodImplOptions.NoInlining)]
78         static void GuardFromEH0 () {
79                 try {
80                         InnerFromEH0 ();
81                 } catch (Exception e) {
82                         if (!(e is ThreadAbortException))
83                                 result |= 0x8;
84                         Console.WriteLine ("caught/2 a {0} while on {1} res {2}", e.GetType (), Thread.CurrentThread.ThreadState, result);
85                 }
86         }
87
88
89         public static int test_0_abort_finally_after_throw () {
90                 finally_done = false;
91                 result = 0;
92                 Action ac = GuardFromEH0;
93                 handle = new ManualResetEvent (false);
94                 var res = ac.BeginInvoke (null, null);
95                 handle.WaitOne ();
96                 Console.WriteLine ("aborting");
97                 thread.Abort ();
98                 Console.WriteLine ("aborted");
99                 res.AsyncWaitHandle.WaitOne ();
100                 Console.WriteLine ("waited");
101                 if (!finally_done)
102                         result |= 0x100;
103                 return result;
104         }
105
106         /////////////////////////////////////////////////////
107
108         [MethodImplAttribute (MethodImplOptions.NoInlining)]
109         static void InnerFromEH1 () {
110                 thread = Thread.CurrentThread;
111                 MethodInfo mi = typeof (Driver).GetMethod ("SleepLoop");
112                 try {
113                         try {
114                                 throw new ArgumentException ();
115                         } finally {     
116                                 handle.Set ();
117                                 SleepLoop ();
118                                 CancelAbort ();
119                                 Console.WriteLine ("done");
120                                 finally_done = true;
121                         }
122                         Console.WriteLine ("After finally");
123                         result |= 0x10;
124                 } catch (Exception e) {
125                         if (!(e is ArgumentException))
126                                 result |= 0x4;
127                         Console.WriteLine ("caught/3 a {0} while on {1} res {2}", e.GetType (), Thread.CurrentThread.ThreadState, result);
128                 }
129         }
130
131         [MethodImplAttribute (MethodImplOptions.NoInlining)]
132         static void GuardFromEH1 () {
133                 try {
134                         InnerFromEH1 ();
135                 } catch (Exception e) {
136                         result |= 0x8;
137                         Console.WriteLine ("caught/4 a {0} while on {1}", e.GetType (), Thread.CurrentThread.ThreadState);
138                 }
139         }
140
141         public static int test_0_abort_finally_and_cancel () {
142                 finally_done = false;
143                 result = 0;
144                 Action ac = GuardFromEH1;
145                 handle = new ManualResetEvent (false);
146                 var res = ac.BeginInvoke (null, null);
147                 handle.WaitOne ();
148                 Console.WriteLine ("aborting");
149                 thread.Abort ();
150                 Console.WriteLine ("aborted");
151                 res.AsyncWaitHandle.WaitOne ();
152                 Console.WriteLine ("waited");
153                 if (!finally_done)
154                         result |= 0x100;
155                 return result;
156         }
157
158         /////////////////////////////////////////////////////
159
160         [MethodImplAttribute (MethodImplOptions.NoInlining)]
161         static void InnerFromEH () {
162                 thread = Thread.CurrentThread;
163                 MethodInfo mi = typeof (Driver).GetMethod ("SleepLoop");
164                 try {
165                         try {
166                                 Console.WriteLine ("try block");
167                         } finally {     
168                                 handle.Set ();
169                                 SleepLoop ();
170                                 Console.WriteLine ("done");
171                                 finally_done = true;
172                         }
173                         Console.WriteLine ("After finally");
174                         result |= 0x10;
175                 } catch (Exception e) {
176                         if (!(e is ThreadAbortException))
177                                 result |= 0x4;
178                         Console.WriteLine ("caught/5 a {0} while on {1} res {2}", e.GetType (), Thread.CurrentThread.ThreadState, result);
179                 }
180         }
181
182         [MethodImplAttribute (MethodImplOptions.NoInlining)]
183         static void GuardFromEH () {
184                 try {
185                         InnerFromEH ();
186                 } catch (Exception e) {
187                         if (!(e is ThreadAbortException))
188                                 result |= 0x8;
189                         Console.WriteLine ("caught/6 a {0} while on {1} res {2}", e.GetType (), Thread.CurrentThread.ThreadState, result);
190                 }
191         }
192
193
194         public static int test_0_finally_after_try () {
195                 AppDomain.CurrentDomain.UnhandledException += (obj, sender) => {
196                         Console.WriteLine ("Unhandled {0}",  sender.ExceptionObject);
197                 };
198
199                 finally_done = false;
200                 result = 0;
201                 Action ac = GuardFromEH;
202                 handle = new ManualResetEvent (false);
203                 var res = ac.BeginInvoke (null, null);
204                 handle.WaitOne ();
205                 Console.WriteLine ("aborting");
206                 thread.Abort ();
207                 Console.WriteLine ("aborted");
208                 res.AsyncWaitHandle.WaitOne ();
209                 Console.WriteLine ("waited");
210                 if (!finally_done)
211                         result |= 0x100;
212                 return result;
213         }
214         /////////////////////////////////////////////////////
215
216         static int Main (string[] args)
217         {
218                 AppDomain.CurrentDomain.UnhandledException += (obj, sender) => {
219                         Console.WriteLine ("Unhandled {0}",  sender.ExceptionObject);
220                 };
221
222                 return TestDriver.RunTests (typeof (Driver), args);
223         }
224 }
225
226