* Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
* Copyright 2004-2009 Novell, Inc (http://www.novell.com)
* Copyright 2012 Xamarin Inc
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/
#undef ASSEMBLY_LOAD_DEBUG
#include <config.h>
* Changes which are already detected at runtime, like the addition
* of icalls, do not require an increment.
*/
-#define MONO_CORLIB_VERSION 140
+#define MONO_CORLIB_VERSION 148
typedef struct
{
static MonoLoadFunc load_function = NULL;
+/* Lazy class loading functions */
+static GENERATE_GET_CLASS_WITH_CACHE (assembly, System.Reflection, Assembly)
+
void
mono_install_runtime_load (MonoLoadFunc func)
{
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, "")));
+ MonoString *empty_str = mono_string_intern_checked (mono_string_new (domain, ""), &error);
+ mono_error_assert_ok (&error);
+ mono_field_static_set_value (string_vt, string_empty_fld, empty_str);
/*
* Create an instance early since we can't do it when there is no memory.
*
*/
void
-mono_runtime_init (MonoDomain *domain, MonoThreadStartCB start_cb,
- MonoThreadAttachCB attach_cb)
+mono_runtime_init (MonoDomain *domain, MonoThreadStartCB start_cb, MonoThreadAttachCB attach_cb)
{
MonoError error;
+ mono_runtime_init_checked (domain, start_cb, attach_cb, &error);
+ mono_error_cleanup (&error);
+}
+
+void
+mono_runtime_init_checked (MonoDomain *domain, MonoThreadStartCB start_cb, MonoThreadAttachCB attach_cb, MonoError *error)
+{
MonoAppDomainSetup *setup;
MonoAppDomain *ad;
MonoClass *klass;
+ mono_error_init (error);
+
mono_portability_helpers_init ();
mono_gc_base_init ();
mono_install_assembly_postload_search_hook ((MonoAssemblySearchFunc)mono_domain_assembly_postload_search, GUINT_TO_POINTER (FALSE));
mono_install_assembly_postload_refonly_search_hook ((MonoAssemblySearchFunc)mono_domain_assembly_postload_search, GUINT_TO_POINTER (TRUE));
mono_install_assembly_load_hook (mono_domain_fire_assembly_load, NULL);
- mono_install_lookup_dynamic_token (mono_reflection_lookup_dynamic_token);
mono_thread_init (start_cb, attach_cb);
- klass = mono_class_from_name (mono_defaults.corlib, "System", "AppDomainSetup");
- setup = (MonoAppDomainSetup *) mono_object_new_pinned (domain, klass, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ klass = mono_class_load_from_name (mono_defaults.corlib, "System", "AppDomainSetup");
+ setup = (MonoAppDomainSetup *) mono_object_new_pinned (domain, klass, error);
+ return_if_nok (error);
+
+ klass = mono_class_load_from_name (mono_defaults.corlib, "System", "AppDomain");
+
+ ad = (MonoAppDomain *) mono_object_new_pinned (domain, klass, error);
+ return_if_nok (error);
- klass = mono_class_from_name (mono_defaults.corlib, "System", "AppDomain");
- ad = (MonoAppDomain *) mono_object_new_pinned (domain, klass, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
ad->data = domain;
domain->domain = ad;
domain->setup = setup;
mono_gc_init ();
/* contexts use GC handles, so they must be initialized after the GC */
- mono_context_init (domain);
+ mono_context_init_checked (domain, error);
+ return_if_nok (error);
mono_context_set (domain->default_context);
#ifndef DISABLE_SOCKETS
static int
mono_get_corlib_version (void)
{
+ MonoError error;
MonoClass *klass;
MonoClassField *field;
MonoObject *value;
- klass = mono_class_from_name (mono_defaults.corlib, "System", "Environment");
+ klass = mono_class_load_from_name (mono_defaults.corlib, "System", "Environment");
mono_class_init (klass);
field = mono_class_get_field_from_name (klass, "mono_corlib_version");
if (!field)
return -1;
if (! (field->type->attrs & FIELD_ATTRIBUTE_STATIC))
return -1;
- value = mono_field_get_value_object (mono_domain_get (), field, NULL);
+ value = mono_field_get_value_object_checked (mono_domain_get (), field, NULL, &error);
+ mono_error_assert_ok (&error);
return *(gint32*)((gchar*)value + sizeof (MonoObject));
}
mono_context_init (MonoDomain *domain)
{
MonoError error;
+ mono_context_init_checked (domain, &error);
+ mono_error_cleanup (&error);
+}
+
+void
+mono_context_init_checked (MonoDomain *domain, MonoError *error)
+{
MonoClass *klass;
MonoAppContext *context;
- klass = mono_class_from_name (mono_defaults.corlib, "System.Runtime.Remoting.Contexts", "Context");
- context = (MonoAppContext *) mono_object_new_pinned (domain, klass, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_error_init (error);
+
+ klass = mono_class_load_from_name (mono_defaults.corlib, "System.Runtime.Remoting.Contexts", "Context");
+ context = (MonoAppContext *) mono_object_new_pinned (domain, klass, error);
+ return_if_nok (error);
+
context->domain_id = domain->domain_id;
context->context_id = 0;
ves_icall_System_Runtime_Remoting_Contexts_Context_RegisterContext (context);
MonoAppDomainSetup *setup;
MonoClass *klass;
- klass = mono_class_from_name (mono_defaults.corlib, "System", "AppDomainSetup");
+ klass = mono_class_load_from_name (mono_defaults.corlib, "System", "AppDomainSetup");
setup = (MonoAppDomainSetup *) mono_object_new_checked (mono_domain_get (), klass, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ if (!is_ok (&error))
+ goto fail;
setup->configuration_file = configuration_file != NULL ? mono_string_new (mono_domain_get (), configuration_file) : NULL;
ad = mono_domain_create_appdomain_internal (friendly_name, setup, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ if (!is_ok (&error))
+ goto fail;
return mono_domain_from_appdomain (ad);
+fail:
+ mono_error_cleanup (&error);
+ return NULL;
}
/**
}
static MonoAppDomainSetup*
-copy_app_domain_setup (MonoDomain *domain, MonoAppDomainSetup *setup)
+copy_app_domain_setup (MonoDomain *domain, MonoAppDomainSetup *setup, MonoError *error)
{
- MonoError error;
- MonoDomain *caller_domain = mono_domain_get ();
- MonoClass *ads_class = mono_class_from_name (mono_defaults.corlib, "System", "AppDomainSetup");
- MonoAppDomainSetup *copy = (MonoAppDomainSetup*)mono_object_new_checked (domain, ads_class, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ MonoDomain *caller_domain;
+ MonoClass *ads_class;
+ MonoAppDomainSetup *copy;
+
+ mono_error_init (error);
+
+ caller_domain = mono_domain_get ();
+ ads_class = mono_class_load_from_name (mono_defaults.corlib, "System", "AppDomainSetup");
+
+ copy = (MonoAppDomainSetup*)mono_object_new_checked (domain, ads_class, error);
+ return_val_if_nok (error, NULL);
mono_domain_set_internal (domain);
- MONO_OBJECT_SETREF (copy, application_base, mono_marshal_xdomain_copy_value ((MonoObject*)setup->application_base));
- MONO_OBJECT_SETREF (copy, application_name, mono_marshal_xdomain_copy_value ((MonoObject*)setup->application_name));
- MONO_OBJECT_SETREF (copy, cache_path, mono_marshal_xdomain_copy_value ((MonoObject*)setup->cache_path));
- MONO_OBJECT_SETREF (copy, configuration_file, mono_marshal_xdomain_copy_value ((MonoObject*)setup->configuration_file));
- MONO_OBJECT_SETREF (copy, dynamic_base, mono_marshal_xdomain_copy_value ((MonoObject*)setup->dynamic_base));
- MONO_OBJECT_SETREF (copy, license_file, mono_marshal_xdomain_copy_value ((MonoObject*)setup->license_file));
- MONO_OBJECT_SETREF (copy, private_bin_path, mono_marshal_xdomain_copy_value ((MonoObject*)setup->private_bin_path));
- MONO_OBJECT_SETREF (copy, private_bin_path_probe, mono_marshal_xdomain_copy_value ((MonoObject*)setup->private_bin_path_probe));
- MONO_OBJECT_SETREF (copy, shadow_copy_directories, mono_marshal_xdomain_copy_value ((MonoObject*)setup->shadow_copy_directories));
- MONO_OBJECT_SETREF (copy, shadow_copy_files, mono_marshal_xdomain_copy_value ((MonoObject*)setup->shadow_copy_files));
+#define XCOPY_FIELD(dst,field,src,error) \
+ do { \
+ MonoObject *copied_val = mono_marshal_xdomain_copy_value ((MonoObject*)(src), error); \
+ return_val_if_nok (error, NULL); \
+ MONO_OBJECT_SETREF ((dst),field,copied_val); \
+ } while (0)
+
+ XCOPY_FIELD (copy, application_base, setup->application_base, error);
+ XCOPY_FIELD (copy, application_name, setup->application_name, error);
+ XCOPY_FIELD (copy, cache_path, setup->cache_path, error);
+ XCOPY_FIELD (copy, configuration_file, setup->configuration_file, error);
+ XCOPY_FIELD (copy, dynamic_base, setup->dynamic_base, error);
+ XCOPY_FIELD (copy, license_file, setup->license_file, error);
+ XCOPY_FIELD (copy, private_bin_path, setup->private_bin_path, error);
+ XCOPY_FIELD (copy, private_bin_path_probe, setup->private_bin_path_probe, error);
+ XCOPY_FIELD (copy, shadow_copy_directories, setup->shadow_copy_directories, error);
+ XCOPY_FIELD (copy, shadow_copy_files, setup->shadow_copy_files, error);
copy->publisher_policy = setup->publisher_policy;
copy->path_changed = setup->path_changed;
copy->loader_optimization = setup->loader_optimization;
copy->disallow_binding_redirects = setup->disallow_binding_redirects;
copy->disallow_code_downloads = setup->disallow_code_downloads;
- MONO_OBJECT_SETREF (copy, domain_initializer_args, mono_marshal_xdomain_copy_value ((MonoObject*)setup->domain_initializer_args));
+ XCOPY_FIELD (copy, domain_initializer_args, setup->domain_initializer_args, error);
copy->disallow_appbase_probe = setup->disallow_appbase_probe;
- MONO_OBJECT_SETREF (copy, application_trust, mono_marshal_xdomain_copy_value ((MonoObject*)setup->application_trust));
- MONO_OBJECT_SETREF (copy, configuration_bytes, mono_marshal_xdomain_copy_value ((MonoObject*)setup->configuration_bytes));
- MONO_OBJECT_SETREF (copy, serialized_non_primitives, mono_marshal_xdomain_copy_value ((MonoObject*)setup->serialized_non_primitives));
+ XCOPY_FIELD (copy, application_trust, setup->application_trust, error);
+ XCOPY_FIELD (copy, configuration_bytes, setup->configuration_bytes, error);
+ XCOPY_FIELD (copy, serialized_non_primitives, setup->serialized_non_primitives, error);
+#undef COPY_FIELD
+
mono_domain_set_internal (caller_domain);
return copy;
MonoDomain *data;
char *shadow_location;
- adclass = mono_class_from_name (mono_defaults.corlib, "System", "AppDomain");
+ mono_error_init (error);
+
+ adclass = mono_class_load_from_name (mono_defaults.corlib, "System", "AppDomain");
/* FIXME: pin all those objects */
data = mono_domain_create();
ad = (MonoAppDomain *) mono_object_new_checked (data, adclass, error);
- if (!mono_error_ok (error)) return NULL;
+ return_val_if_nok (error, NULL);
ad->data = data;
data->domain = ad;
data->friendly_name = g_strdup (friendly_name);
}
}
- mono_context_init (data);
+ mono_context_init_checked (data, error);
+ return_val_if_nok (error, NULL);
+
+ data->setup = copy_app_domain_setup (data, setup, error);
+ if (!mono_error_ok (error)) {
+ g_free (data->friendly_name);
+ return NULL;
+ }
- data->setup = copy_app_domain_setup (data, setup);
mono_domain_set_options_from_config (data);
add_assemblies_to_domain (data, mono_defaults.corlib->assembly, NULL);
#ifndef DISABLE_SHADOW_COPY
/*FIXME, guard this for when the debugger is not running */
shadow_location = get_shadow_assembly_location_base (data, error);
- if (!mono_error_ok (error))
+ if (!mono_error_ok (error)) {
+ g_free (data->friendly_name);
return NULL;
+ }
g_free (shadow_location);
#endif
mono_domain_try_type_resolve (MonoDomain *domain, char *name, MonoObject *tb)
{
MonoError error;
+ MonoReflectionAssembly *ret = mono_domain_try_type_resolve_checked (domain, name, tb, &error);
+ mono_error_cleanup (&error);
+
+ return ret;
+}
+
+MonoReflectionAssembly *
+mono_domain_try_type_resolve_checked (MonoDomain *domain, char *name, MonoObject *tb, MonoError *error)
+{
+ static MonoMethod *method = NULL;
MonoReflectionAssembly *ret;
MonoClass *klass;
void *params [1];
- static MonoMethod *method = NULL;
+
+ mono_error_init (error);
g_assert (domain != NULL && ((name != NULL) || (tb != NULL)));
else
*params = tb;
- ret = (MonoReflectionAssembly *) mono_runtime_invoke_checked (method, domain->domain, params, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ ret = (MonoReflectionAssembly *) mono_runtime_invoke_checked (method, domain->domain, params, error);
+ return_val_if_nok (error, NULL);
return ret;
}
MonoAppDomain *
ves_icall_System_AppDomain_createDomain (MonoString *friendly_name, MonoAppDomainSetup *setup)
{
+ MonoError error;
+ MonoAppDomain *ad = NULL;
#ifdef DISABLE_APPDOMAINS
- mono_set_pending_exception (mono_get_exception_not_supported ("AppDomain creation is not supported on this runtime."));
- return NULL;
+ mono_error_set_not_supported (&error, "AppDomain creation is not supported on this runtime.");
#else
- MonoError error;
char *fname;
- MonoAppDomain *ad;
fname = mono_string_to_utf8 (friendly_name);
ad = mono_domain_create_appdomain_internal (fname, setup, &error);
g_free (fname);
-
- mono_error_raise_exception (&error);
-
- return ad;
#endif
+ mono_error_set_pending_exception (&error);
+ return ad;
}
MonoArray *
MonoError error;
MonoDomain *domain = ad->data;
MonoAssembly* ass;
- static MonoClass *System_Reflection_Assembly;
MonoArray *res;
GSList *tmp;
int i;
GPtrArray *assemblies;
mono_error_init (&error);
-
- if (!System_Reflection_Assembly)
- System_Reflection_Assembly = mono_class_from_name (
- mono_defaults.corlib, "System.Reflection", "Assembly");
/*
* Make a copy of the list of assemblies because we can't hold the assemblies
}
mono_domain_assemblies_unlock (domain);
- res = mono_array_new (domain, System_Reflection_Assembly, assemblies->len);
+ res = mono_array_new_checked (domain, mono_class_get_assembly_class (), assemblies->len, &error);
+ if (!is_ok (&error))
+ goto leave;
for (i = 0; i < assemblies->len; ++i) {
ass = (MonoAssembly *)g_ptr_array_index (assemblies, i);
MonoReflectionAssembly *ass_obj = mono_assembly_get_object_checked (domain, ass, &error);
}
MonoReflectionAssembly *
-mono_try_assembly_resolve (MonoDomain *domain, MonoString *fname, MonoAssembly *requesting, gboolean refonly)
+mono_try_assembly_resolve (MonoDomain *domain, MonoString *fname, MonoAssembly *requesting, gboolean refonly, MonoError *error)
{
- MonoError error;
MonoReflectionAssembly *ret;
MonoClass *klass;
MonoMethod *method;
MonoBoolean isrefonly;
gpointer params [3];
+ mono_error_init (error);
+
if (mono_runtime_get_no_exec ())
return NULL;
isrefonly = refonly ? 1 : 0;
params [0] = fname;
if (requesting) {
- params[1] = mono_assembly_get_object_checked (domain, requesting, &error);
- if (!mono_error_ok (&error))
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ params[1] = mono_assembly_get_object_checked (domain, requesting, error);
+ return_val_if_nok (error, NULL);
} else
params [1] = NULL;
params [2] = &isrefonly;
- ret = (MonoReflectionAssembly *) mono_runtime_invoke_checked (method, domain->domain, params, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ ret = (MonoReflectionAssembly *) mono_runtime_invoke_checked (method, domain->domain, params, error);
+ return_val_if_nok (error, NULL);
return ret;
}
mono_domain_assembly_postload_search (MonoAssemblyName *aname, MonoAssembly *requesting,
gboolean refonly)
{
+ MonoError error;
MonoReflectionAssembly *assembly;
MonoDomain *domain = mono_domain_get ();
char *aname_str;
/* FIXME: We invoke managed code here, so there is a potential for deadlocks */
str = mono_string_new (domain, aname_str);
+ g_free (aname_str);
if (!str) {
- g_free (aname_str);
return NULL;
}
- assembly = mono_try_assembly_resolve (domain, str, requesting, refonly);
- g_free (aname_str);
+
+ assembly = mono_try_assembly_resolve (domain, str, requesting, refonly, &error);
+ mono_error_cleanup (&error);
if (assembly)
return assembly->assembly;
*params = ref_assembly;
mono_runtime_invoke_checked (assembly_load_method, domain->domain, params, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_error_cleanup (&error);
}
/*
if (!mono_error_ok (&error)) {
mono_error_cleanup (&error);
g_free (dir_name);
- mono_error_set_generic_error (oerror, "System", "ExecutionEngineException", "Failed to create shadow copy (invalid characters in shadow directory name).");
+ mono_error_set_execution_engine (oerror, "Failed to create shadow copy (invalid characters in shadow directory name).");
return NULL;
}
shadow = get_shadow_assembly_location (filename, &error);
if (!mono_error_ok (&error)) {
mono_error_cleanup (&error);
- mono_error_set_generic_error (oerror, "System", "ExecutionEngineException", "Failed to create shadow copy (invalid characters in file name).");
+ mono_error_set_execution_engine (oerror, "Failed to create shadow copy (invalid characters in file name).");
return NULL;
}
if (ensure_directory_exists (shadow) == FALSE) {
g_free (shadow);
- mono_error_set_generic_error (oerror, "System", "ExecutionEngineException", "Failed to create shadow copy (ensure directory exists).");
+ mono_error_set_execution_engine (oerror, "Failed to create shadow copy (ensure directory exists).");
return NULL;
}
if (GetLastError() == ERROR_FILE_NOT_FOUND || GetLastError() == ERROR_PATH_NOT_FOUND)
return NULL; /* file not found, shadow copy failed */
- mono_error_set_generic_error (oerror, "System", "ExecutionEngineException", "Failed to create shadow copy (CopyFile).");
+ mono_error_set_execution_engine (oerror, "Failed to create shadow copy (CopyFile).");
return NULL;
}
if (copy_result == FALSE) {
g_free (shadow);
- mono_error_set_generic_error (oerror, "System", "ExecutionEngineException", "Failed to create shadow copy of sibling data (CopyFile).");
+ mono_error_set_execution_engine (oerror, "Failed to create shadow copy of sibling data (CopyFile).");
return NULL;
}
/* Create a .ini file containing the original assembly location */
if (!shadow_copy_create_ini (shadow, filename)) {
g_free (shadow);
- mono_error_set_generic_error (oerror, "System", "ExecutionEngineException", "Failed to create shadow copy .ini file.");
+ mono_error_set_execution_engine (oerror, "Failed to create shadow copy .ini file.");
return NULL;
}
if (!parsed) {
/* This is a parse error... */
- if (!refOnly)
- refass = mono_try_assembly_resolve (domain, assRef, NULL, refOnly);
+ if (!refOnly) {
+ refass = mono_try_assembly_resolve (domain, assRef, NULL, refOnly, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
+ }
return refass;
}
if (!ass) {
/* MS.NET doesn't seem to call the assembly resolve handler for refonly assemblies */
- if (!refOnly)
- refass = mono_try_assembly_resolve (domain, assRef, NULL, refOnly);
+ if (!refOnly) {
+ refass = mono_try_assembly_resolve (domain, assRef, NULL, refOnly, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
+ }
else
refass = NULL;
if (!refass) {
void
ves_icall_System_AppDomain_InternalUnload (gint32 domain_id)
{
+ MonoException *exc = NULL;
MonoDomain * domain = mono_domain_get_by_id (domain_id);
if (NULL == domain) {
- MonoException *exc = mono_get_exception_execution_engine ("Failed to unload domain, domain id not found");
+ mono_get_exception_execution_engine ("Failed to unload domain, domain id not found");
mono_set_pending_exception (exc);
return;
}
return;
#endif
- mono_domain_unload (domain);
+ mono_domain_try_unload (domain, (MonoObject**)&exc);
+ if (exc)
+ mono_set_pending_exception (exc);
}
gboolean
if (!method)
g_error ("No entry point method found in %s due to %s", image->name, mono_error_get_message (&error));
- if (!args)
- args = (MonoArray *) mono_array_new (ad->data, mono_defaults.string_class, 0);
+ if (!args) {
+ args = (MonoArray *) mono_array_new_checked (ad->data, mono_defaults.string_class, 0, &error);
+ mono_error_assert_ok (&error);
+ }
return mono_runtime_exec_main (method, (MonoArray *)args, NULL);
}
MonoError error;
MonoString *res = NULL;
res = mono_string_new_utf16_checked (mono_domain_get (), process_guid, sizeof(process_guid)/2, &error);
- mono_error_raise_exception (&error);
+ mono_error_set_pending_exception (&error);
return res;
}
memcpy (process_guid, mono_string_chars(newguid), sizeof(process_guid));
/* Have to attach to the runtime so shutdown can wait for this thread */
/* Force it to be attached to avoid racing during shutdown. */
- thread = mono_thread_attach_full (mono_get_root_domain (), TRUE, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ thread = mono_thread_attach_full (mono_get_root_domain (), TRUE);
+
+ mono_thread_set_name_internal (thread->internal_thread, mono_string_new (mono_get_root_domain (), "Domain unloader"), TRUE, &error);
+ if (!is_ok (&error)) {
+ data->failure_reason = g_strdup (mono_error_get_message (&error));
+ mono_error_cleanup (&error);
+ goto failure;
+ }
/*
* FIXME: Abort our parent thread last, so we can return a failure
{
MonoObject *exc = NULL;
mono_domain_try_unload (domain, &exc);
- if (exc)
- mono_raise_exception ((MonoException*)exc);
}
static guint32
{
guint32 result;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
result = WaitForSingleObjectEx (handle, timeout, alertable);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return result;
}
unload_data *thread_data;
MonoNativeThreadId tid;
MonoDomain *caller_domain = mono_domain_get ();
- char *name;
/* printf ("UNLOAD STARTING FOR %s (%p) IN THREAD 0x%x.\n", domain->friendly_name, domain, mono_native_thread_id_get ()); */
thread_handle = mono_threads_create_thread ((LPTHREAD_START_ROUTINE)unload_thread_main, thread_data, 0, CREATE_SUSPENDED, &tid);
if (thread_handle == NULL)
return;
- name = g_strdup_printf ("Unload thread for domain %x", domain);
- mono_thread_info_set_name (tid, name);
mono_thread_info_resume (tid);
- g_free (name);
/* Wait for the thread */
while (!thread_data->done && guarded_wait (thread_handle, INFINITE, TRUE) == WAIT_IO_COMPLETION) {