[Profiler] Use the correct function to increment the refcount
[mono.git] / mono / tests / appdomain-unload.cs
1 using System;
2 using System.Threading;
3 using System.Reflection;
4 using System.Runtime.Remoting;
5
6 [Serializable]
7 public class Foo {
8
9         ~Foo () {
10                 Console.WriteLine ("FINALIZING IN DOMAIN " + AppDomain.CurrentDomain.FriendlyName + ": " + AppDomain.CurrentDomain.IsFinalizingForUnload ());
11         }
12 }
13
14 public class Bar : MarshalByRefObject {
15         public int test (int x) {
16                 Console.WriteLine ("in " + Thread.GetDomain ().FriendlyName);
17                 return x + 1;
18         }
19 }
20
21 [Serializable]
22 public class SlowFinalize {
23
24         ~SlowFinalize () {
25                 Console.WriteLine ("FINALIZE1.");
26                 try {
27                         Thread.Sleep (500);
28                 }
29                 catch (Exception ex) {
30                         Console.WriteLine ("A: " + ex);
31                 }
32                 Console.WriteLine ("FINALIZE2.");
33         }
34 }
35
36 [Serializable]
37 public class AThread {
38
39         public AThread () {
40                 new Thread (new ThreadStart (Run)).Start ();
41         }
42
43         public void Run () {
44                 try {
45                         while (true)
46                                 Thread.Sleep (100);
47                 }
48                 catch (ThreadAbortException ex) {
49                         Console.WriteLine ("Thread aborted correctly.");
50                 }
51         }
52 }
53
54 // A Thread which refuses to die
55 public class BThread : MarshalByRefObject {
56
57         bool stop;
58
59         public BThread () {
60                 new Thread (new ThreadStart (Run)).Start ();
61         }
62
63         public void Stop () {
64                 stop = true;
65         }
66
67         public void Run () {
68                 try {
69                         while (true)
70                                 Thread.Sleep (100);
71                 }
72                 catch (ThreadAbortException ex) {
73                         while (!stop)
74                                 Thread.Sleep (100);
75                 }
76         }
77 }
78
79 public class UnloadThread {
80
81         AppDomain domain;
82
83         public UnloadThread (AppDomain domain) {
84                 this.domain = domain;
85         }
86
87         public void Run () {
88                 Console.WriteLine ("UNLOAD1");
89                 AppDomain.Unload (domain);
90                 Console.WriteLine ("UNLOAD2");
91         }
92 }
93
94 class CrossDomainTester : MarshalByRefObject
95 {
96 }
97
98 public class Tests
99 {
100         public static int Main(string[] args) {
101                 return TestDriver.RunTests (typeof (Tests), args);
102         }
103
104         public static int test_0_unload () {
105                 for (int i = 0; i < 10; ++i) {
106                         AppDomain appDomain = AppDomain.CreateDomain("Test-unload" + i);
107
108                         appDomain.CreateInstanceAndUnwrap (
109                                 typeof (CrossDomainTester).Assembly.FullName, "CrossDomainTester");
110
111                         AppDomain.Unload(appDomain);
112                 }
113
114                 return 0;
115         }
116
117         public static int test_0_unload_default () {
118                 try {
119                         AppDomain.Unload (Thread.GetDomain ());
120                 }
121                 catch (CannotUnloadAppDomainException) {
122                         return 0;
123                 }
124                 return 1;
125         }
126
127         public static int test_0_unload_after_unload () {
128                 AppDomain domain = AppDomain.CreateDomain ("Test2");
129                 AppDomain.Unload (domain);
130
131                 try {
132                         AppDomain.Unload (domain);
133                 }
134                 catch (Exception) {
135                         return 0;
136                 }
137
138                 return 1;
139         }
140
141         public static int test_0_is_finalizing () {
142                 AppDomain domain = AppDomain.CreateDomain ("Test-is-finalizing");
143                 object o = domain.CreateInstanceFromAndUnwrap (typeof (Tests).Assembly.Location, "Foo");
144
145                 if (domain.IsFinalizingForUnload ())
146                         return 1;
147
148                 AppDomain.Unload (domain);
149
150                 return 0;
151         }
152
153         public static int test_0_unload_with_active_threads () {
154                 AppDomain domain = AppDomain.CreateDomain ("Test3");
155                 object o = domain.CreateInstanceFromAndUnwrap (typeof (Tests).Assembly.Location, "AThread");
156                 Thread.Sleep (100);
157
158                 AppDomain.Unload (domain);
159
160                 return 0;
161         }
162
163         /* In recent mono versions, there is no unload timeout */
164         /*
165         public static int test_0_unload_with_active_threads_timeout () {
166                 AppDomain domain = AppDomain.CreateDomain ("Test4");
167                 BThread o = (BThread)domain.CreateInstanceFromAndUnwrap (typeof (Tests).Assembly.Location, "BThread");
168                 Thread.Sleep (100);
169
170                 try {
171                         AppDomain.Unload (domain);
172                 }
173                 catch (Exception) {
174                         // Try again
175                         o.Stop ();
176                         AppDomain.Unload (domain);
177                         return 0;
178                 }
179
180                 return 1;
181         }
182         */
183
184         static void Worker (object x) {
185                 Thread.Sleep (100000);
186         }
187
188         public static void invoke_workers () {
189                 for (int i = 0; i < 1; i ++)
190                         ThreadPool.QueueUserWorkItem (Worker);
191         }
192
193         public static int test_0_unload_with_threadpool () {
194                 AppDomain domain = AppDomain.CreateDomain ("test_0_unload_with_threadpool");
195
196                 domain.DoCallBack (new CrossAppDomainDelegate (invoke_workers));
197                 AppDomain.Unload (domain);
198
199                 return 0;
200         }
201
202         /*
203          * This test is not very deterministic since the thread which enqueues
204          * the work item might or might not be inside the domain when the unload
205          * happens. So disable this for now.
206          */
207         /*
208         public static void DoUnload (object state) {
209                 AppDomain.Unload (AppDomain.CurrentDomain);
210         }
211
212         public static void Callback () {
213                 Console.WriteLine (AppDomain.CurrentDomain);
214                 WaitCallback unloadDomainCallback = new WaitCallback (DoUnload);
215                 ThreadPool.QueueUserWorkItem (unloadDomainCallback);
216         }               
217
218         public static int test_0_unload_inside_appdomain_async () {
219                 AppDomain domain = AppDomain.CreateDomain ("Test3");
220
221                 domain.DoCallBack (new CrossAppDomainDelegate (Callback));
222
223                 return 0;
224         }
225         */
226
227         public static void SyncCallback () {
228                 AppDomain.Unload (AppDomain.CurrentDomain);
229         }               
230
231         public static int test_0_unload_inside_appdomain_sync () {
232                 AppDomain domain = AppDomain.CreateDomain ("Test3");
233
234                 try {
235                         domain.DoCallBack (new CrossAppDomainDelegate (SyncCallback));
236                 }
237                 catch (Exception ex) {
238                         /* Should throw a ThreadAbortException */
239                         Thread.ResetAbort ();
240                 }
241
242                 return 0;
243         }
244
245         public static int test_0_invoke_after_unload () {
246                 AppDomain domain = AppDomain.CreateDomain ("DeadInvokeTest");
247                 Bar bar = (Bar)domain.CreateInstanceAndUnwrap (typeof (Tests).Assembly.FullName, "Bar");
248                 int x;
249
250                 if (!RemotingServices.IsTransparentProxy(bar))
251                         return 3;
252
253                 AppDomain.Unload (domain);
254
255                 try {
256                         x = bar.test (123);
257                         if (x == 124)
258                                 return 1;
259                         return 2;
260                 } catch (Exception e) {
261                         return 0;
262                 }
263         }
264
265         // FIXME: This does not work yet, because the thread is finalized too
266         // early
267         /*
268         public static int test_0_unload_during_unload () {
269                 AppDomain domain = AppDomain.CreateDomain ("Test3");
270                 object o = domain.CreateInstanceFromAndUnwrap (typeof (Tests).Assembly.Location, "SlowFinalize");
271
272                 UnloadThread t = new UnloadThread (domain);
273
274                 // Start unloading in a separate thread
275                 new Thread (new ThreadStart (t.Run)).Start ();
276
277                 Thread.Sleep (100);
278
279                 try {
280                         AppDomain.Unload (domain);
281                 }
282                 catch (Exception) {
283                         Console.WriteLine ("OK");
284                 }
285
286                 return 0;
287         }       
288 */
289 }
290