Merge pull request #2819 from BrzVlad/fix-major-log
[mono.git] / mono / metadata / runtime.c
index 276a519f0d3d7d8b5b9bcd52dd0057367ebdf1f4..1c41c797db4fa2c235cd84398bf04cdf7f45541b 100644 (file)
@@ -5,6 +5,7 @@
  *  Jonathan Pryor 
  *
  * Copyright 2010 Novell, Inc (http://www.novell.com)
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
 #include <config.h>
 #include <mono/metadata/class-internals.h>
 #include <mono/metadata/runtime.h>
 #include <mono/metadata/monitor.h>
+#include <mono/metadata/threads-types.h>
+#include <mono/metadata/threadpool-ms.h>
+#include <mono/metadata/marshal.h>
+#include <mono/utils/atomic.h>
+
+static gboolean shutting_down_inited = FALSE;
+static gboolean shutting_down = FALSE;
+
+/** 
+ * mono_runtime_set_shutting_down:
+ *
+ * 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)
+{
+       shutting_down = TRUE;
+}
+
+/**
+ * mono_runtime_is_shutting_down:
+ *
+ * Returns whether the runtime has been flagged for shutdown.
+ *
+ * This is consumed by the P:System.Environment.HasShutdownStarted
+ * property.
+ *
+ */
+gboolean
+mono_runtime_is_shutting_down (void)
+{
+       return shutting_down;
+}
 
 static void
 fire_process_exit_event (MonoDomain *domain, gpointer user_data)
@@ -36,17 +73,68 @@ fire_process_exit_event (MonoDomain *domain, gpointer user_data)
        mono_runtime_delegate_invoke (delegate, pa, &exc);
 }
 
-void
-mono_runtime_shutdown (void)
+static void
+mono_runtime_fire_process_exit_event (void)
 {
+#ifndef MONO_CROSS_COMPILE
        mono_domain_foreach (fire_process_exit_event, NULL);
+#endif
+}
+
+
+/**
+ * mono_runtime_try_shutdown:
+ *
+ * Try to initialize runtime shutdown.
+ *
+ * After this call completes the thread pool will stop accepting new jobs and no further threads will be created.
+ *
+ * Returns: 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_threadpool_ms_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;
 }
 
 
 gboolean
 mono_runtime_is_critical_method (MonoMethod *method)
 {
-       if (mono_monitor_is_il_fastpath_wrapper (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_init_tls ();
+}