Merge pull request #1857 from slluis/fix-assembly-resolver
[mono.git] / mono / metadata / appdomain.c
index 1944b7edcdfb95d677796a40b57382e706a14e0b..b3742cb943fceff38b5601b7ae8662ff2c7f2c63 100644 (file)
  * of classes the runtime knows about, changing icall signature or
  * semantics etc), increment this variable. Also increment the
  * pair of this variable in mscorlib in:
- *       mcs/class/mscorlib/System/Environment.cs
+ *       mcs/class/corlib/System/Environment.cs
  *
  * Changes which are already detected at runtime, like the addition
  * of icalls, do not require an increment.
  */
-#define MONO_CORLIB_VERSION 117
+#define MONO_CORLIB_VERSION 134
 
 typedef struct
 {
@@ -90,8 +90,6 @@ typedef struct
 
 mono_mutex_t mono_delegate_section;
 
-mono_mutex_t mono_strtod_mutex;
-
 static gunichar2 process_guid [36];
 static gboolean process_guid_set = FALSE;
 
@@ -163,12 +161,23 @@ create_domain_objects (MonoDomain *domain)
 {
        MonoDomain *old_domain = mono_domain_get ();
        MonoString *arg;
+       MonoVTable *string_vt;
+       MonoClassField *string_empty_fld;
 
        if (domain != old_domain) {
                mono_thread_push_appdomain_ref (domain);
                mono_domain_set_internal_with_options (domain, FALSE);
        }
 
+       /*
+        * Initialize String.Empty. This enables the removal of
+        * the static cctor of the String class.
+        */
+       string_vt = mono_class_vtable (domain, mono_defaults.string_class);
+       string_empty_fld = mono_class_get_field_from_name (mono_defaults.string_class, "Empty");
+       g_assert (string_empty_fld);
+       mono_field_static_set_value (string_vt, string_empty_fld, mono_string_intern (mono_string_new (domain, "")));
+
        /*
         * Create an instance early since we can't do it when there is no memory.
         */
@@ -247,12 +256,8 @@ mono_runtime_init (MonoDomain *domain, MonoThreadStartCB start_cb,
        domain->setup = setup;
 
        mono_mutex_init_recursive (&mono_delegate_section);
-
-       mono_mutex_init_recursive (&mono_strtod_mutex);
        
        mono_thread_attach (domain);
-       mono_context_init (domain);
-       mono_context_set (domain->default_context);
 
        mono_type_initialization_init ();
 
@@ -262,6 +267,10 @@ mono_runtime_init (MonoDomain *domain, MonoThreadStartCB start_cb,
        /* GC init has to happen after thread init */
        mono_gc_init ();
 
+       /* contexts use GC handles, so they must be initialized after the GC */
+       mono_context_init (domain);
+       mono_context_set (domain->default_context);
+
 #ifndef DISABLE_SOCKETS
        mono_network_init ();
 #endif
@@ -329,6 +338,7 @@ mono_context_init (MonoDomain *domain)
        context = (MonoAppContext *) mono_object_new_pinned (domain, class);
        context->domain_id = domain->domain_id;
        context->context_id = 0;
+       ves_icall_System_Runtime_Remoting_Contexts_Context_RegisterContext (context);
        domain->default_context = context;
 }
 
@@ -2349,6 +2359,18 @@ mono_domain_unload (MonoDomain *domain)
                mono_raise_exception ((MonoException*)exc);
 }
 
+static guint32
+guarded_wait (HANDLE handle, guint32 timeout, gboolean alertable)
+{
+       guint32 result;
+
+       MONO_PREPARE_BLOCKING
+       result = WaitForSingleObjectEx (handle, timeout, alertable);
+       MONO_FINISH_BLOCKING
+
+       return result;
+}
+
 /*
  * mono_domain_unload:
  * @domain: The domain to unload
@@ -2435,7 +2457,7 @@ mono_domain_try_unload (MonoDomain *domain, MonoObject **exc)
        g_free (name);
 
        /* Wait for the thread */       
-       while (!thread_data->done && WaitForSingleObjectEx (thread_handle, INFINITE, TRUE) == WAIT_IO_COMPLETION) {
+       while (!thread_data->done && guarded_wait (thread_handle, INFINITE, TRUE) == WAIT_IO_COMPLETION) {
                if (mono_thread_internal_has_appdomain_ref (mono_thread_internal_current (), domain) && (mono_thread_interruption_requested ())) {
                        /* The unload thread tries to abort us */
                        /* The icall wrapper will execute the abort */