using System;
using System.Threading;
+using System.Reflection;
+using System.Runtime.Remoting;
[Serializable]
public class Foo {
}
}
+public class Bar : MarshalByRefObject {
+ public int test (int x) {
+ Console.WriteLine ("in " + Thread.GetDomain ().FriendlyName);
+ return x + 1;
+ }
+}
+
[Serializable]
public class SlowFinalize {
}
}
-[Serializable]
// A Thread which refuses to die
-public class BThread {
+public class BThread : MarshalByRefObject {
+
+ bool stop;
public BThread () {
new Thread (new ThreadStart (Run)).Start ();
}
+ public void Stop () {
+ stop = true;
+ }
+
public void Run () {
try {
while (true)
Thread.Sleep (100);
}
catch (ThreadAbortException ex) {
- Thread.Sleep (1000000000);
+ while (!stop)
+ Thread.Sleep (100);
}
}
}
}
}
+class CrossDomainTester : MarshalByRefObject
+{
+}
+
public class Tests
{
- public static int Main() {
- return TestDriver.RunTests (typeof (Tests));
+ public static int Main(string[] args) {
+ return TestDriver.RunTests (typeof (Tests), args);
}
public static int test_0_unload () {
for (int i = 0; i < 10; ++i) {
AppDomain appDomain = AppDomain.CreateDomain("Test-unload" + i);
+
+ appDomain.CreateInstanceAndUnwrap (
+ typeof (CrossDomainTester).Assembly.FullName, "CrossDomainTester");
+
AppDomain.Unload(appDomain);
}
public static int test_0_is_finalizing () {
AppDomain domain = AppDomain.CreateDomain ("Test-is-finalizing");
- object o = domain.CreateInstanceFromAndUnwrap ("unload.exe", "Foo");
+ object o = domain.CreateInstanceFromAndUnwrap (typeof (Tests).Assembly.Location, "Foo");
if (domain.IsFinalizingForUnload ())
return 1;
public static int test_0_unload_with_active_threads () {
AppDomain domain = AppDomain.CreateDomain ("Test3");
- object o = domain.CreateInstanceFromAndUnwrap ("unload.exe", "AThread");
+ object o = domain.CreateInstanceFromAndUnwrap (typeof (Tests).Assembly.Location, "AThread");
Thread.Sleep (100);
AppDomain.Unload (domain);
return 0;
}
+ /* In recent mono versions, there is no unload timeout */
+ /*
public static int test_0_unload_with_active_threads_timeout () {
AppDomain domain = AppDomain.CreateDomain ("Test4");
- object o = domain.CreateInstanceFromAndUnwrap ("unload.exe", "BThread");
+ BThread o = (BThread)domain.CreateInstanceFromAndUnwrap (typeof (Tests).Assembly.Location, "BThread");
Thread.Sleep (100);
try {
AppDomain.Unload (domain);
}
catch (Exception) {
+ // Try again
+ o.Stop ();
+ AppDomain.Unload (domain);
return 0;
}
return 1;
}
+ */
+
+ static void Worker (object x) {
+ Thread.Sleep (100000);
+ }
+
+ public static void invoke_workers () {
+ for (int i = 0; i < 1; i ++)
+ ThreadPool.QueueUserWorkItem (Worker);
+ }
+
+ public static int test_0_unload_with_threadpool () {
+ AppDomain domain = AppDomain.CreateDomain ("test_0_unload_with_threadpool");
+
+ domain.DoCallBack (new CrossAppDomainDelegate (invoke_workers));
+ AppDomain.Unload (domain);
+
+ return 0;
+ }
+
+ /*
+ * This test is not very deterministic since the thread which enqueues
+ * the work item might or might not be inside the domain when the unload
+ * happens. So disable this for now.
+ */
+ /*
+ public static void DoUnload (object state) {
+ AppDomain.Unload (AppDomain.CurrentDomain);
+ }
+
+ public static void Callback () {
+ Console.WriteLine (AppDomain.CurrentDomain);
+ WaitCallback unloadDomainCallback = new WaitCallback (DoUnload);
+ ThreadPool.QueueUserWorkItem (unloadDomainCallback);
+ }
+
+ public static int test_0_unload_inside_appdomain_async () {
+ AppDomain domain = AppDomain.CreateDomain ("Test3");
+
+ domain.DoCallBack (new CrossAppDomainDelegate (Callback));
+
+ return 0;
+ }
+ */
+
+ public static void SyncCallback () {
+ AppDomain.Unload (AppDomain.CurrentDomain);
+ }
+
+ public static int test_0_unload_inside_appdomain_sync () {
+ AppDomain domain = AppDomain.CreateDomain ("Test3");
+
+ try {
+ domain.DoCallBack (new CrossAppDomainDelegate (SyncCallback));
+ }
+ catch (Exception ex) {
+ /* Should throw a ThreadAbortException */
+ Thread.ResetAbort ();
+ }
+
+ return 0;
+ }
+
+ public static int test_0_invoke_after_unload () {
+ AppDomain domain = AppDomain.CreateDomain ("DeadInvokeTest");
+ Bar bar = (Bar)domain.CreateInstanceAndUnwrap (typeof (Tests).Assembly.FullName, "Bar");
+ int x;
+
+ if (!RemotingServices.IsTransparentProxy(bar))
+ return 3;
+
+ AppDomain.Unload (domain);
+
+ try {
+ x = bar.test (123);
+ if (x == 124)
+ return 1;
+ return 2;
+ } catch (Exception e) {
+ return 0;
+ }
+ }
// FIXME: This does not work yet, because the thread is finalized too
// early
/*
public static int test_0_unload_during_unload () {
AppDomain domain = AppDomain.CreateDomain ("Test3");
- object o = domain.CreateInstanceFromAndUnwrap ("unload.exe", "SlowFinalize");
+ object o = domain.CreateInstanceFromAndUnwrap (typeof (Tests).Assembly.Location, "SlowFinalize");
UnloadThread t = new UnloadThread (domain);