2005-06-09 Lluis Sanchez Gual <lluis@novell.com>
[mono.git] / mono / tests / appdomain-unload.cs
1 using System;
2 using System.Threading;
3
4 [Serializable]
5 public class Foo {
6
7         ~Foo () {
8                 Console.WriteLine ("FINALIZING IN DOMAIN " + AppDomain.CurrentDomain.FriendlyName + ": " + AppDomain.CurrentDomain.IsFinalizingForUnload ());
9         }
10 }
11
12 [Serializable]
13 public class SlowFinalize {
14
15         ~SlowFinalize () {
16                 Console.WriteLine ("FINALIZE1.");
17                 try {
18                         Thread.Sleep (500);
19                 }
20                 catch (Exception ex) {
21                         Console.WriteLine ("A: " + ex);
22                 }
23                 Console.WriteLine ("FINALIZE2.");
24         }
25 }
26
27 [Serializable]
28 public class AThread {
29
30         public AThread () {
31                 new Thread (new ThreadStart (Run)).Start ();
32         }
33
34         public void Run () {
35                 try {
36                         while (true)
37                                 Thread.Sleep (100);
38                 }
39                 catch (ThreadAbortException ex) {
40                         Console.WriteLine ("Thread aborted correctly.");
41                 }
42         }
43 }
44
45 // A Thread which refuses to die
46 public class BThread : MarshalByRefObject {
47
48         bool stop;
49
50         public BThread () {
51                 new Thread (new ThreadStart (Run)).Start ();
52         }
53
54         public void Stop () {
55                 stop = true;
56         }
57
58         public void Run () {
59                 try {
60                         while (true)
61                                 Thread.Sleep (100);
62                 }
63                 catch (ThreadAbortException ex) {
64                         while (!stop)
65                                 Thread.Sleep (100);
66                 }
67         }
68 }
69
70 public class UnloadThread {
71
72         AppDomain domain;
73
74         public UnloadThread (AppDomain domain) {
75                 this.domain = domain;
76         }
77
78         public void Run () {
79                 Console.WriteLine ("UNLOAD1");
80                 AppDomain.Unload (domain);
81                 Console.WriteLine ("UNLOAD2");
82         }
83 }
84
85 public class Tests
86 {
87         public static int Main() {
88                 return TestDriver.RunTests (typeof (Tests));
89         }
90
91         public static int test_0_unload () {
92                 for (int i = 0; i < 10; ++i) {
93                         AppDomain appDomain = AppDomain.CreateDomain("Test-unload" + i);
94                         AppDomain.Unload(appDomain);
95                 }
96
97                 return 0;
98         }
99
100         public static int test_0_unload_default () {
101                 try {
102                         AppDomain.Unload (Thread.GetDomain ());
103                 }
104                 catch (CannotUnloadAppDomainException) {
105                         return 0;
106                 }
107                 return 1;
108         }
109
110         public static int test_0_unload_after_unload () {
111                 AppDomain domain = AppDomain.CreateDomain ("Test2");
112                 AppDomain.Unload (domain);
113
114                 try {
115                         AppDomain.Unload (domain);
116                 }
117                 catch (Exception) {
118                         return 0;
119                 }
120
121                 return 1;
122         }
123
124         public static int test_0_is_finalizing () {
125                 AppDomain domain = AppDomain.CreateDomain ("Test-is-finalizing");
126                 object o = domain.CreateInstanceFromAndUnwrap (typeof (Tests).Assembly.Location, "Foo");
127
128                 if (domain.IsFinalizingForUnload ())
129                         return 1;
130
131                 AppDomain.Unload (domain);
132
133                 return 0;
134         }
135
136         public static int test_0_unload_with_active_threads () {
137                 AppDomain domain = AppDomain.CreateDomain ("Test3");
138                 object o = domain.CreateInstanceFromAndUnwrap (typeof (Tests).Assembly.Location, "AThread");
139                 Thread.Sleep (100);
140
141                 AppDomain.Unload (domain);
142
143                 return 0;
144         }
145
146         public static int test_0_unload_with_active_threads_timeout () {
147                 AppDomain domain = AppDomain.CreateDomain ("Test4");
148                 BThread o = (BThread)domain.CreateInstanceFromAndUnwrap (typeof (Tests).Assembly.Location, "BThread");
149                 Thread.Sleep (100);
150
151                 try {
152                         AppDomain.Unload (domain);
153                 }
154                 catch (Exception) {
155                         // Try again
156                         o.Stop ();
157                         AppDomain.Unload (domain);
158                         return 0;
159                 }
160
161                 return 1;
162         }
163
164         /*
165          * This test is not very deterministic since the thread which enqueues
166          * the work item might or might not be inside the domain when the unload
167          * happens. So disable this for now.
168          */
169         /*
170         public static void DoUnload (object state) {
171                 AppDomain.Unload (AppDomain.CurrentDomain);
172         }
173
174         public static void Callback () {
175                 Console.WriteLine (AppDomain.CurrentDomain);
176                 WaitCallback unloadDomainCallback = new WaitCallback (DoUnload);
177                 ThreadPool.QueueUserWorkItem (unloadDomainCallback);
178         }               
179
180         public static int test_0_unload_inside_appdomain_async () {
181                 AppDomain domain = AppDomain.CreateDomain ("Test3");
182
183                 domain.DoCallBack (new CrossAppDomainDelegate (Callback));
184
185                 return 0;
186         }
187         */
188
189         public static void SyncCallback () {
190                 AppDomain.Unload (AppDomain.CurrentDomain);
191         }               
192
193         public static int test_0_unload_inside_appdomain_sync () {
194                 AppDomain domain = AppDomain.CreateDomain ("Test3");
195
196                 try {
197                         domain.DoCallBack (new CrossAppDomainDelegate (SyncCallback));
198                 }
199                 catch (Exception ex) {
200                         /* Should throw a ThreadAbortException */
201                         Thread.ResetAbort ();
202                 }
203
204                 return 0;
205         }
206
207         // FIXME: This does not work yet, because the thread is finalized too
208         // early
209         /*
210         public static int test_0_unload_during_unload () {
211                 AppDomain domain = AppDomain.CreateDomain ("Test3");
212                 object o = domain.CreateInstanceFromAndUnwrap (typeof (Tests).Assembly.Location, "SlowFinalize");
213
214                 UnloadThread t = new UnloadThread (domain);
215
216                 // Start unloading in a separate thread
217                 new Thread (new ThreadStart (t.Run)).Start ();
218
219                 Thread.Sleep (100);
220
221                 try {
222                         AppDomain.Unload (domain);
223                 }
224                 catch (Exception) {
225                         Console.WriteLine ("OK");
226                 }
227
228                 return 0;
229         }       
230 */
231 }
232