[docs] Enable documentation for metadata.
[mono.git] / mono / metadata / runtime.c
1 /**
2  * \file
3  * Runtime functions
4  *
5  * Authors:
6  *  Jonathan Pryor 
7  *
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.
10  */
11
12 #include <config.h>
13
14 #include <glib.h>
15
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
26 static gboolean shutting_down_inited = FALSE;
27 static gboolean shutting_down = FALSE;
28
29 /** 
30  * mono_runtime_set_shutting_down:
31  *
32  * Invoked by System.Environment.Exit to flag that the runtime
33  * is shutting down.
34  *
35  * Deprecated. This function can break the shutdown sequence.
36  */
37 void
38 mono_runtime_set_shutting_down (void)
39 {
40         shutting_down = TRUE;
41 }
42
43 /**
44  * mono_runtime_is_shutting_down:
45  *
46  * Returns whether the runtime has been flagged for shutdown.
47  *
48  * This is consumed by the P:System.Environment.HasShutdownStarted
49  * property.
50  *
51  */
52 gboolean
53 mono_runtime_is_shutting_down (void)
54 {
55         return shutting_down;
56 }
57
58 static void
59 fire_process_exit_event (MonoDomain *domain, gpointer user_data)
60 {
61         MonoError error;
62         MonoClassField *field;
63         gpointer pa [2];
64         MonoObject *delegate, *exc;
65
66         field = mono_class_get_field_from_name (mono_defaults.appdomain_class, "ProcessExit");
67         g_assert (field);
68
69         delegate = *(MonoObject **)(((char *)domain->domain) + field->offset); 
70         if (delegate == NULL)
71                 return;
72
73         pa [0] = domain;
74         pa [1] = NULL;
75         mono_runtime_delegate_try_invoke (delegate, pa, &exc, &error);
76         mono_error_cleanup (&error);
77 }
78
79 static void
80 mono_runtime_fire_process_exit_event (void)
81 {
82 #ifndef MONO_CROSS_COMPILE
83         mono_domain_foreach (fire_process_exit_event, NULL);
84 #endif
85 }
86
87
88 /**
89  * mono_runtime_try_shutdown:
90  *
91  * Try to initialize runtime shutdown.
92  *
93  * After this call completes the thread pool will stop accepting new jobs and no further threads will be created.
94  *
95  * Returns: TRUE if shutdown was initiated by this call or false is other thread beat this one.
96  */
97 gboolean
98 mono_runtime_try_shutdown (void)
99 {
100         if (InterlockedCompareExchange (&shutting_down_inited, TRUE, FALSE))
101                 return FALSE;
102
103         mono_runtime_fire_process_exit_event ();
104
105         shutting_down = TRUE;
106
107         mono_threads_set_shutting_down ();
108
109         /* No new threads will be created after this point */
110
111         mono_runtime_set_shutting_down ();
112
113         /*TODO move the follow to here:
114         mono_thread_suspend_all_other_threads (); OR  mono_thread_wait_all_other_threads
115
116         mono_runtime_quit ();
117         */
118
119         return TRUE;
120 }
121
122
123 gboolean
124 mono_runtime_is_critical_method (MonoMethod *method)
125 {
126         return FALSE;
127 }
128
129 /*
130 Coordinate the creation of all remaining TLS slots in the runtime.
131 No further TLS slots should be created after this function finishes.
132 This restriction exists because AOT requires offsets to be constant
133 across runs.
134 */
135 void
136 mono_runtime_init_tls (void)
137 {
138         mono_marshal_init_tls ();
139 }
140
141 char*
142 mono_runtime_get_aotid (void)
143 {
144         int i;
145         guint8 aotid_sum = 0;
146         MonoDomain* domain = mono_domain_get ();
147
148         if (!domain->entry_assembly || !domain->entry_assembly->image)
149                 return NULL;
150
151         guint8 (*aotid)[16] = &domain->entry_assembly->image->aotid;
152
153         for (i = 0; i < 16; ++i)
154                 aotid_sum |= (*aotid)[i];
155
156         if (aotid_sum == 0)
157                 return NULL;
158
159         return mono_guid_to_string ((guint8*) aotid);
160 }