[2020-02] Fix leak in assembly-specific dllmap lookups (#21053)
[mono-project.git] / mono / metadata / runtime.c
blob4d42ee45141bf5f1e965fff1a45981769d8b7e2d
1 /**
2 * \file
3 * Runtime functions
5 * Authors:
6 * Jonathan Pryor
8 * Copyright 2010 Novell, Inc (http://www.novell.com)
9 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
12 #include <config.h>
14 #include <glib.h>
16 #include <mono/metadata/appdomain.h>
17 #include <mono/metadata/class.h>
18 #include <mono/metadata/class-internals.h>
19 #include <mono/metadata/runtime.h>
20 #include <mono/metadata/monitor.h>
21 #include <mono/metadata/threads-types.h>
22 #include <mono/metadata/threadpool.h>
23 #include <mono/metadata/marshal.h>
24 #include <mono/utils/atomic.h>
25 #include <mono/utils/unlocked.h>
27 static gboolean shutting_down_inited = FALSE;
28 static gboolean shutting_down = FALSE;
30 /**
31 * mono_runtime_set_shutting_down:
32 * \deprecated This function can break the shutdown sequence.
34 * Invoked by \c System.Environment.Exit to flag that the runtime
35 * is shutting down.
37 void
38 mono_runtime_set_shutting_down (void)
40 UnlockedWriteBool (&shutting_down, TRUE);
43 /**
44 * mono_runtime_is_shutting_down:
45 * This is consumed by the \c P:System.Environment.HasShutdownStarted property.
46 * \returns whether the runtime has been flagged for shutdown.
48 gboolean
49 mono_runtime_is_shutting_down (void)
51 return UnlockedReadBool (&shutting_down);
54 static void
55 fire_process_exit_event (MonoDomain *domain, gpointer user_data)
57 ERROR_DECL (error);
58 MonoObject *exc;
60 #if ENABLE_NETCORE
61 MonoClass *appcontext_class;
62 MonoMethod *procexit_method;
64 appcontext_class = mono_class_try_load_from_name (mono_defaults.corlib, "System", "AppContext");
65 g_assert (appcontext_class);
67 procexit_method = mono_class_get_method_from_name_checked (appcontext_class, "OnProcessExit", 0, 0, error);
68 g_assert (procexit_method);
70 mono_runtime_try_invoke (procexit_method, NULL, NULL, &exc, error);
71 #else
72 MonoClassField *field;
73 gpointer pa [2];
74 MonoObject *delegate;
76 field = mono_class_get_field_from_name_full (mono_defaults.appdomain_class, "ProcessExit", NULL);
77 g_assert (field);
79 delegate = *(MonoObject **)(((char *)domain->domain) + field->offset);
80 if (delegate == NULL)
81 return;
83 pa [0] = domain->domain;
84 pa [1] = NULL;
85 mono_runtime_delegate_try_invoke (delegate, pa, &exc, error);
86 mono_error_cleanup (error);
87 #endif
90 static void
91 mono_runtime_fire_process_exit_event (void)
93 #ifndef MONO_CROSS_COMPILE
94 mono_domain_foreach (fire_process_exit_event, NULL);
95 #endif
98 /**
99 * mono_runtime_try_shutdown:
101 * Try to initialize runtime shutdown.
103 * After this call completes the thread pool will stop accepting new jobs and no further threads will be created.
105 * Returns: TRUE if shutdown was initiated by this call or false is other thread beat this one.
107 gboolean
108 mono_runtime_try_shutdown (void)
110 if (mono_atomic_cas_i32 (&shutting_down_inited, TRUE, FALSE))
111 return FALSE;
113 mono_runtime_fire_process_exit_event ();
115 mono_runtime_set_shutting_down ();
117 mono_threads_set_shutting_down ();
119 /* No new threads will be created after this point */
121 /*TODO move the follow to here:
122 mono_thread_suspend_all_other_threads (); OR mono_thread_wait_all_other_threads
124 mono_runtime_quit_internal ();
127 return TRUE;
131 Coordinate the creation of all remaining TLS slots in the runtime.
132 No further TLS slots should be created after this function finishes.
133 This restriction exists because AOT requires offsets to be constant
134 across runs.
136 void
137 mono_runtime_init_tls (void)
139 mono_marshal_init_tls ();
142 guint8*
143 mono_runtime_get_aotid_arr (void)
145 int i;
146 guint8 aotid_sum = 0;
147 MonoDomain* domain = mono_domain_get ();
149 if (!domain->entry_assembly || !domain->entry_assembly->image)
150 return NULL;
152 guint8 (*aotid)[16] = &domain->entry_assembly->image->aotid;
153 for (i = 0; i < 16; ++i)
154 aotid_sum |= (*aotid)[i];
156 if (aotid_sum == 0)
157 return NULL;
159 return (guint8*)aotid;
162 char*
163 mono_runtime_get_aotid (void)
165 guint8 *aotid = mono_runtime_get_aotid_arr ();
167 if (!aotid)
168 return NULL;
170 return mono_guid_to_string (aotid);