Merge pull request #711 from spicypixel/hotfix/appdomain-leak
[mono.git] / mono / metadata / runtime.c
index 289d0184435ea36a444590ba186df396e3304c7f..7b14f436536eb13fb0b509a6c2645ccd816bcda8 100644 (file)
 #include <mono/metadata/runtime.h>
 #include <mono/metadata/monitor.h>
 #include <mono/metadata/threads-types.h>
+#include <mono/metadata/threadpool.h>
+#include <mono/metadata/marshal.h>
+#include <mono/utils/atomic.h>
 
+static gboolean shutting_down_inited = FALSE;
 static gboolean shutting_down = FALSE;
 
 /** 
@@ -25,6 +29,8 @@ static gboolean shutting_down = FALSE;
  *
  * Invoked by System.Environment.Exit to flag that the runtime
  * is shutting down.
+ *
+ * Deprecated. This function can break the shutdown sequence.
  */
 void
 mono_runtime_set_shutting_down (void)
@@ -74,22 +80,39 @@ mono_runtime_fire_process_exit_event (void)
 #endif
 }
 
-/*
-Initialize runtime shutdown.
-After this call completes the thread pool will stop accepting new jobs and
 
-*/
-void
-mono_runtime_shutdown (void)
+/*
+ * Try to initialize runtime shutdown.
+ * After this call completes the thread pool will stop accepting new jobs and no further threads will be created.
+ *
+ * @return true if shutdown was initiated by this call or false is other thread beat this one
+ */
+gboolean
+mono_runtime_try_shutdown (void)
 {
+       if (InterlockedCompareExchange (&shutting_down_inited, TRUE, FALSE))
+               return FALSE;
+
        mono_runtime_fire_process_exit_event ();
 
+       shutting_down = TRUE;
+
        mono_threads_set_shutting_down ();
 
        /* No new threads will be created after this point */
 
        mono_runtime_set_shutting_down ();
 
+       /* This will kill the tp threads which cannot be suspended */
+       mono_thread_pool_cleanup ();
+
+       /*TODO move the follow to here:
+       mono_thread_suspend_all_other_threads (); OR  mono_thread_wait_all_other_threads
+
+       mono_runtime_quit ();
+       */
+
+       return TRUE;
 }
 
 
@@ -100,3 +123,17 @@ mono_runtime_is_critical_method (MonoMethod *method)
                return TRUE;
        return FALSE;
 }
+
+/*
+Coordinate the creation of all remaining TLS slots in the runtime.
+No further TLS slots should be created after this function finishes.
+This restriction exists because AOT requires offsets to be constant
+across runs.
+*/
+void
+mono_runtime_init_tls (void)
+{
+       mono_marshal_init_tls ();
+       mono_thread_pool_init_tls ();
+       mono_thread_init_tls ();
+}