Merge pull request #505 from roji/shutdown_flow
authorRodrigo Kumpera <kumpera@gmail.com>
Tue, 12 Mar 2013 21:25:47 +0000 (14:25 -0700)
committerRodrigo Kumpera <kumpera@gmail.com>
Tue, 12 Mar 2013 21:25:47 +0000 (14:25 -0700)
Fixed threadpool+ProcessExit problem in shutdown flow

mono/metadata/icall.c
mono/metadata/threads.c
mono/mini/mini.c
mono/tests/Makefile.am
mono/tests/threadpool-in-processexit.cs [new file with mode: 0644]
mono/tests/threadpool-in-processexit.exe.stdout.expected [new file with mode: 0644]

index 1be47527f85a564707224dea6249fee79cf892c6..ed34f324fc96e03b17aa06a093c71102e58b846a 100644 (file)
@@ -73,6 +73,7 @@
 #include <mono/metadata/mono-debug.h>
 #include <mono/metadata/mono-ptr-array.h>
 #include <mono/metadata/verify-internals.h>
+#include <mono/metadata/runtime.h>
 #include <mono/io-layer/io-layer.h>
 #include <mono/utils/strtod.h>
 #include <mono/utils/monobitset.h>
@@ -6529,6 +6530,10 @@ ves_icall_System_Environment_Exit (int result)
 {
        MONO_ARCH_SAVE_REGS;
 
+#ifndef MONO_CROSS_COMPILE
+       mono_runtime_shutdown ();
+#endif
+
        mono_threads_set_shutting_down ();
 
        mono_runtime_set_shutting_down ();
index 0809e076bd87d6e3c1ec10f2b082d9146e6d989a..56a1ea2646be71194ebe78c192d034ce8c60dd2f 100644 (file)
@@ -33,6 +33,7 @@
 #include <mono/metadata/monitor.h>
 #include <mono/metadata/gc-internal.h>
 #include <mono/metadata/marshal.h>
+#include <mono/metadata/runtime.h>
 #include <mono/io-layer/io-layer.h>
 #ifndef HOST_WIN32
 #include <mono/io-layer/threads.h>
@@ -2906,6 +2907,10 @@ void mono_thread_manage (void)
                THREAD_DEBUG (g_message ("%s: I have %d threads after waiting.", __func__, wait->num));
        } while(wait->num>0);
 
+#ifndef MONO_CROSS_COMPILE
+       mono_runtime_shutdown ();
+#endif
+
        mono_threads_set_shutting_down ();
 
        /* No new threads will be created after this point */
index 6c9d1c0a3789934627cd009a90b2b84d27e373c2..28b66be959ff9fe33df01979916b3dd65ec2cc44 100644 (file)
@@ -7201,12 +7201,9 @@ mini_cleanup (MonoDomain *domain)
 #endif
 
 #ifndef MONO_CROSS_COMPILE     
-       mono_runtime_shutdown ();
        /* 
-        * mono_runtime_cleanup() and mono_domain_finalize () need to
-        * be called early since they need the execution engine still
-        * fully working (mono_domain_finalize may invoke managed finalizers
-        * and mono_runtime_cleanup will wait for other threads to finish).
+        * mono_domain_finalize () needs to be called early since it needs the
+        * execution engine still fully working (it may invoke managed finalizers).
         */
        mono_domain_finalize (domain, 2000);
 #endif
index d13a92979bc8b9f9880e601c57da40d754683ded..455a4b159409ec7d342845a5cc1b01e7fb533627 100644 (file)
@@ -1062,12 +1062,16 @@ patch-libtool:
        sed -e 's,LIBTOOL =,LIBTOOL2 =,g' Makefile > 2 && echo "LIBTOOL = bash ./libtool" > 1 && cat 1 2 > Makefile
        touch libtest.c
 
-EXTRA_DIST += bug-438454.cs bug-438454.exe.stdout.expected
+EXTRA_DIST += bug-438454.cs bug-438454.exe.stdout.expected threadpool-in-processexit.cs threadpool-in-processexit.exe.stdout.expected
 test-process-exit:
        @$(MCS) $(srcdir)/bug-438454.cs -out:bug-438454.exe
        @echo "Testing bug-438454.exe..."
        @$(RUNTIME) bug-438454.exe > bug-438454.exe.stdout
        @diff -w bug-438454.exe.stdout $(srcdir)/bug-438454.exe.stdout.expected
+       @$(MCS) $(srcdir)/threadpool-in-processexit.cs -out:threadpool-in-processexit.exe
+       @echo "Testing threadpool-in-processexit.exe..."
+       @$(RUNTIME) threadpool-in-processexit.exe > threadpool-in-processexit.exe.stdout
+       @diff -w threadpool-in-processexit.exe.stdout $(srcdir)/threadpool-in-processexit.exe.stdout.expected
 
 OOM_TESTS =    \
        gc-oom-handling.exe     \
diff --git a/mono/tests/threadpool-in-processexit.cs b/mono/tests/threadpool-in-processexit.cs
new file mode 100644 (file)
index 0000000..4300396
--- /dev/null
@@ -0,0 +1,26 @@
+using System;
+using System.Threading;
+
+class Program
+{
+       static AutoResetEvent mre = new AutoResetEvent(false);
+
+       static void Main ()
+       {
+               AppDomain.CurrentDomain.ProcessExit += SomeEndOfProcessAction;
+       }
+
+       static void SomeEndOfProcessAction(object sender, EventArgs args)
+       {
+               ThreadPool.QueueUserWorkItem (new WaitCallback (ThreadPoolCallback));
+               if (mre.WaitOne(1000))
+                       Console.WriteLine ("PASS");
+               else
+                       Console.WriteLine ("FAIL");
+       }
+
+       static void ThreadPoolCallback (object state)
+       {
+               mre.Set ();
+       }
+}
diff --git a/mono/tests/threadpool-in-processexit.exe.stdout.expected b/mono/tests/threadpool-in-processexit.exe.stdout.expected
new file mode 100644 (file)
index 0000000..7ef22e9
--- /dev/null
@@ -0,0 +1 @@
+PASS