X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fappdomain.c;h=02ca3bbf949dcfa99b1b35c56eccea187d7bfbb3;hb=010fcfb9ecfef1654b415dbb909a01148a89e827;hp=2849c7b406f8e6f5659925ce152ea2f2f40c77f2;hpb=ae1822075d7c697ec4d96f9be96e9b62a7adf386;p=mono.git diff --git a/mono/metadata/appdomain.c b/mono/metadata/appdomain.c index 2849c7b406f..02ca3bbf949 100644 --- a/mono/metadata/appdomain.c +++ b/mono/metadata/appdomain.c @@ -1,5 +1,6 @@ -/* - * appdomain.c: AppDomain functions +/** + * \file + * AppDomain functions * * Authors: * Dietmar Maurer (dietmar@ximian.com) @@ -75,19 +76,6 @@ #include #endif -/* - * This is the version number of the corlib-runtime interface. When - * making changes to this interface (by changing the layout - * 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/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 164 - typedef struct { int runtime_count; @@ -123,6 +111,9 @@ static MonoDomain * mono_domain_create_appdomain_checked (char *friendly_name, char *configuration_file, MonoError *error); +static void +mono_context_set_default_context (MonoDomain *domain); + static char * get_shadow_assembly_location_base (MonoDomain *domain, MonoError *error); @@ -201,7 +192,9 @@ create_domain_objects (MonoDomain *domain) 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); - MonoString *empty_str = mono_string_intern_checked (mono_string_new (domain, ""), &error); + MonoString *empty_str = mono_string_new_checked (domain, "", &error); + mono_error_assert_ok (&error); + empty_str = mono_string_intern_checked (empty_str, &error); mono_error_assert_ok (&error); mono_field_static_set_value (string_vt, string_empty_fld, empty_str); domain->empty_string = empty_str; @@ -209,7 +202,8 @@ create_domain_objects (MonoDomain *domain) /* * Create an instance early since we can't do it when there is no memory. */ - arg = mono_string_new (domain, "Out of memory"); + arg = mono_string_new_checked (domain, "Out of memory", &error); + mono_error_assert_ok (&error); domain->out_of_memory_ex = mono_exception_from_name_two_strings_checked (mono_defaults.corlib, "System", "OutOfMemoryException", arg, NULL, &error); mono_error_assert_ok (&error); @@ -217,10 +211,12 @@ create_domain_objects (MonoDomain *domain) * These two are needed because the signal handlers might be executing on * an alternate stack, and Boehm GC can't handle that. */ - arg = mono_string_new (domain, "A null value was found where an object instance was required"); + arg = mono_string_new_checked (domain, "A null value was found where an object instance was required", &error); + mono_error_assert_ok (&error); domain->null_reference_ex = mono_exception_from_name_two_strings_checked (mono_defaults.corlib, "System", "NullReferenceException", arg, NULL, &error); mono_error_assert_ok (&error); - arg = mono_string_new (domain, "The requested operation caused a stack overflow."); + arg = mono_string_new_checked (domain, "The requested operation caused a stack overflow.", &error); + mono_error_assert_ok (&error); domain->stack_overflow_ex = mono_exception_from_name_two_strings_checked (mono_defaults.corlib, "System", "StackOverflowException", arg, NULL, &error); mono_error_assert_ok (&error); @@ -242,14 +238,14 @@ create_domain_objects (MonoDomain *domain) /** * mono_runtime_init: - * @domain: domain returned by mono_init () + * \param domain domain returned by \c mono_init * * Initialize the core AppDomain: this function will run also some * IL initialization code, so it needs the execution engine to be fully * operational. * - * AppDomain.SetupInformation is set up in mono_runtime_exec_main, where - * we know the entry_assembly. + * \c AppDomain.SetupInformation is set up in \c mono_runtime_exec_main, where + * we know the \c entry_assembly. * */ void @@ -311,7 +307,7 @@ mono_runtime_init_checked (MonoDomain *domain, MonoThreadStartCB start_cb, MonoT /* contexts use GC handles, so they must be initialized after the GC */ mono_context_init_checked (domain, error); return_if_nok (error); - mono_context_set (domain->default_context); + mono_context_set_default_context (domain); #ifndef DISABLE_SOCKETS mono_network_init (); @@ -328,6 +324,15 @@ mono_runtime_init_checked (MonoDomain *domain, MonoThreadStartCB start_cb, MonoT return; } +static void +mono_context_set_default_context (MonoDomain *domain) +{ + HANDLE_FUNCTION_ENTER (); + mono_context_set_handle (MONO_HANDLE_NEW (MonoAppContext, domain->default_context)); + HANDLE_FUNCTION_RETURN (); +} + + static int mono_get_corlib_version (void) { @@ -349,11 +354,9 @@ mono_get_corlib_version (void) } /** - * mono_check_corlib_version - * + * mono_check_corlib_version: * Checks that the corlib that is loaded matches the version of this runtime. - * - * Returns: NULL if the runtime will work with the corlib, or a g_malloc + * \returns NULL if the runtime will work with the corlib, or a \c g_malloc * allocated string with the error otherwise. */ const char* @@ -374,9 +377,8 @@ mono_check_corlib_version (void) /** * mono_context_init: - * @domain: The domain where the System.Runtime.Remoting.Context.Context is initialized - * - * Initializes the @domain's default System.Runtime.Remoting's Context. + * \param domain The domain where the \c System.Runtime.Remoting.Context.Context is initialized + * Initializes the \p domain's default \c System.Runtime.Remoting 's Context. */ void mono_context_init (MonoDomain *domain) @@ -400,13 +402,14 @@ mono_context_init_checked (MonoDomain *domain, MonoError *error) context->domain_id = domain->domain_id; context->context_id = 0; - ves_icall_System_Runtime_Remoting_Contexts_Context_RegisterContext (context); + mono_threads_register_app_context (context, error); + mono_error_assert_ok (error); domain->default_context = context; } /** * mono_runtime_cleanup: - * @domain: unused. + * \param domain unused. * * Internal routine. * @@ -435,12 +438,18 @@ mono_runtime_cleanup (MonoDomain *domain) static MonoDomainFunc quit_function = NULL; +/** + * mono_install_runtime_cleanup: + */ void mono_install_runtime_cleanup (MonoDomainFunc func) { quit_function = func; } +/** + * mono_runtime_quit: + */ void mono_runtime_quit () { @@ -450,10 +459,9 @@ mono_runtime_quit () /** * mono_domain_create_appdomain: - * @friendly_name: The friendly name of the appdomain to create - * @configuration_file: The configuration file to initialize the appdomain with - * - * Returns a MonoDomain initialized with the appdomain + * \param friendly_name The friendly name of the appdomain to create + * \param configuration_file The configuration file to initialize the appdomain with + * \returns a \c MonoDomain initialized with the appdomain */ MonoDomain * mono_domain_create_appdomain (char *friendly_name, char *configuration_file) @@ -467,11 +475,11 @@ mono_domain_create_appdomain (char *friendly_name, char *configuration_file) /** * mono_domain_create_appdomain_checked: - * @friendly_name: The friendly name of the appdomain to create - * @configuration_file: The configuration file to initialize the appdomain with - * @error: Set on error. + * \param friendly_name The friendly name of the appdomain to create + * \param configuration_file The configuration file to initialize the appdomain with + * \param error Set on error. * - * Returns a MonoDomain initialized with the appdomain. On failure sets @error and returns NULL. + * \returns a MonoDomain initialized with the appdomain. On failure sets \p error and returns NULL. */ MonoDomain * mono_domain_create_appdomain_checked (char *friendly_name, char *configuration_file, MonoError *error) @@ -505,9 +513,9 @@ leave: /** * mono_domain_set_config: - * @domain: MonoDomain initialized with the appdomain we want to change - * @base_dir: new base directory for the appdomain - * @config_file_name: path to the new configuration for the app domain + * \param domain \c MonoDomain initialized with the appdomain we want to change + * \param base_dir new base directory for the appdomain + * \param config_file_name path to the new configuration for the app domain * * Used to set the system configuration for an appdomain * @@ -518,8 +526,28 @@ leave: void mono_domain_set_config (MonoDomain *domain, const char *base_dir, const char *config_file_name) { - MONO_OBJECT_SETREF (domain->setup, application_base, mono_string_new (domain, base_dir)); - MONO_OBJECT_SETREF (domain->setup, configuration_file, mono_string_new (domain, config_file_name)); + HANDLE_FUNCTION_ENTER (); + MonoError error; + mono_domain_set_config_checked (domain, base_dir, config_file_name, &error); + mono_error_cleanup (&error); + HANDLE_FUNCTION_RETURN (); +} + +gboolean +mono_domain_set_config_checked (MonoDomain *domain, const char *base_dir, const char *config_file_name, MonoError *error) +{ + error_init (error); + MonoAppDomainSetupHandle setup = MONO_HANDLE_NEW (MonoAppDomainSetup, domain->setup); + MonoStringHandle base_dir_str = mono_string_new_handle (domain, base_dir, error); + if (!is_ok (error)) + goto leave; + MONO_HANDLE_SET (setup, application_base, base_dir_str); + MonoStringHandle config_file_name_str = mono_string_new_handle (domain, config_file_name, error); + if (!is_ok (error)) + goto leave; + MONO_HANDLE_SET (setup, configuration_file, config_file_name_str); +leave: + return is_ok (error); } static MonoAppDomainSetupHandle @@ -662,10 +690,9 @@ leave: /** * mono_domain_has_type_resolve: - * @domain: application domains being looked up + * \param domain application domain being looked up * - * Returns: TRUE if the AppDomain.TypeResolve field has been - * set. + * \returns TRUE if the \c AppDomain.TypeResolve field has been set. */ gboolean mono_domain_has_type_resolve (MonoDomain *domain) @@ -688,16 +715,16 @@ mono_domain_has_type_resolve (MonoDomain *domain) /** * mono_domain_try_type_resolve: - * @domain: application domainwhere the name where the type is going to be resolved - * @name: the name of the type to resolve or NULL. - * @tb: A System.Reflection.Emit.TypeBuilder, used if name is NULL. + * \param domain application domainwhere the name where the type is going to be resolved + * \param name the name of the type to resolve or NULL. + * \param tb A \c System.Reflection.Emit.TypeBuilder, used if name is NULL. * - * This routine invokes the internal System.AppDomain.DoTypeResolve and returns + * This routine invokes the internal \c System.AppDomain.DoTypeResolve and returns * the assembly that matches name. * - * If @name is null, the value of ((TypeBuilder)tb).FullName is used instead + * If \p name is null, the value of \c ((TypeBuilder)tb).FullName is used instead * - * Returns: A MonoReflectionAssembly or NULL if not found + * \returns A \c MonoReflectionAssembly or NULL if not found */ MonoReflectionAssembly * mono_domain_try_type_resolve (MonoDomain *domain, char *name, MonoObject *tb) @@ -728,9 +755,10 @@ mono_domain_try_type_resolve_checked (MonoDomain *domain, char *name, MonoObject } } - if (name) - *params = (MonoObject*)mono_string_new (mono_domain_get (), name); - else + if (name) { + *params = (MonoObject*)mono_string_new_checked (mono_domain_get (), name, error); + return_val_if_nok (error, NULL); + } else *params = tb; ret = (MonoReflectionAssembly *) mono_runtime_invoke_checked (method, domain->domain, params, error); @@ -741,8 +769,7 @@ mono_domain_try_type_resolve_checked (MonoDomain *domain, char *name, MonoObject /** * mono_domain_owns_vtable_slot: - * - * Returns whenever VTABLE_SLOT is inside a vtable which belongs to DOMAIN. + * \returns Whether \p vtable_slot is inside a vtable which belongs to \p domain. */ gboolean mono_domain_owns_vtable_slot (MonoDomain *domain, gpointer vtable_slot) @@ -757,15 +784,13 @@ mono_domain_owns_vtable_slot (MonoDomain *domain, gpointer vtable_slot) /** * mono_domain_set: - * @domain: domain - * @force: force setting. + * \param domain domain + * \param force force setting. * - * Set the current appdomain to @domain. If @force is set, set it even + * Set the current appdomain to \p domain. If \p force is set, set it even * if it is being unloaded. * - * Returns: - * TRUE on success; - * FALSE if the domain is unloaded + * \returns TRUE on success; FALSE if the domain is unloaded */ gboolean mono_domain_set (MonoDomain *domain, gboolean force) @@ -1123,6 +1148,7 @@ leave: MonoAssembly* mono_try_assembly_resolve_handle (MonoDomain *domain, MonoStringHandle fname, MonoAssembly *requesting, gboolean refonly, MonoError *error) { + HANDLE_FUNCTION_ENTER (); MonoAssembly *ret = NULL; MonoMethod *method; MonoBoolean isrefonly; @@ -1131,7 +1157,7 @@ mono_try_assembly_resolve_handle (MonoDomain *domain, MonoStringHandle fname, Mo error_init (error); if (mono_runtime_get_no_exec ()) - return ret; + goto leave; g_assert (domain != NULL && !MONO_HANDLE_IS_NULL (fname)); @@ -1142,14 +1168,16 @@ mono_try_assembly_resolve_handle (MonoDomain *domain, MonoStringHandle fname, Mo MonoReflectionAssemblyHandle requesting_handle; if (requesting) { requesting_handle = mono_assembly_get_object_handle (domain, requesting, error); - return_val_if_nok (error, ret); + if (!is_ok (error)) + goto leave; } params [0] = MONO_HANDLE_RAW (fname); params[1] = requesting ? MONO_HANDLE_RAW (requesting_handle) : NULL; params [2] = &isrefonly; MonoReflectionAssemblyHandle result = MONO_HANDLE_NEW (MonoReflectionAssembly, mono_runtime_invoke_checked (method, domain->domain, params, error)); ret = !MONO_HANDLE_IS_NULL (result) ? MONO_HANDLE_GETVAL (result, assembly) : NULL; - return ret; +leave: + HANDLE_FUNCTION_RETURN_VAL (ret); } MonoAssembly * @@ -1188,12 +1216,13 @@ add_assemblies_to_domain (MonoDomain *domain, MonoAssembly *ass, GHashTable *ht) if (!ht) { ht = g_hash_table_new (mono_aligned_addr_hash, NULL); destroy_ht = TRUE; + for (tmp = domain->domain_assemblies; tmp; tmp = tmp->next) { + g_hash_table_insert (ht, tmp->data, tmp->data); + } } /* FIXME: handle lazy loaded assemblies */ - for (tmp = domain->domain_assemblies; tmp; tmp = tmp->next) { - g_hash_table_insert (ht, tmp->data, tmp->data); - } + if (!g_hash_table_lookup (ht, ass)) { mono_assembly_addref (ass); g_hash_table_insert (ht, ass, ass); @@ -1202,11 +1231,12 @@ add_assemblies_to_domain (MonoDomain *domain, MonoAssembly *ass, GHashTable *ht) } if (ass->image->references) { - for (i = 0; ass->image->references [i] != NULL; i++) { - if (ass->image->references [i] != REFERENCE_MISSING) + for (i = 0; i < ass->image->nreferences; i++) { + if (ass->image->references[i] && ass->image->references [i] != REFERENCE_MISSING) { if (!g_hash_table_lookup (ht, ass->image->references [i])) { add_assemblies_to_domain (domain, ass->image->references [i], ht); } + } } } if (destroy_ht) @@ -1216,6 +1246,7 @@ add_assemblies_to_domain (MonoDomain *domain, MonoAssembly *ass, GHashTable *ht) static void mono_domain_fire_assembly_load (MonoAssembly *assembly, gpointer user_data) { + HANDLE_FUNCTION_ENTER (); static MonoClassField *assembly_load_field; static MonoMethod *assembly_load_method; MonoError error; @@ -1226,7 +1257,7 @@ mono_domain_fire_assembly_load (MonoAssembly *assembly, gpointer user_data) if (!domain->domain) /* This can happen during startup */ - return; + goto leave; #ifdef ASSEMBLY_LOAD_DEBUG fprintf (stderr, "Loading %s into domain %s\n", assembly->aname.name, domain->friendly_name); #endif @@ -1244,7 +1275,7 @@ mono_domain_fire_assembly_load (MonoAssembly *assembly, gpointer user_data) mono_field_get_value ((MonoObject*) domain->domain, assembly_load_field, &load_value); if (load_value == NULL) { /* No events waiting to be triggered */ - return; + goto leave; } MonoReflectionAssemblyHandle ref_assembly = mono_assembly_get_object_handle (domain, assembly, &error); @@ -1259,6 +1290,8 @@ mono_domain_fire_assembly_load (MonoAssembly *assembly, gpointer user_data) mono_runtime_invoke_checked (assembly_load_method, domain->domain, params, &error); mono_error_cleanup (&error); +leave: + HANDLE_FUNCTION_RETURN (); } /* @@ -1839,8 +1872,10 @@ mono_make_shadow_copy (const char *filename, MonoError *oerror) sibling_source_len = strlen (sibling_source); sibling_target = g_strconcat (shadow, ".config", NULL); sibling_target_len = strlen (sibling_target); - + copy_result = shadow_copy_sibling (sibling_source, sibling_source_len, ".mdb", sibling_target, sibling_target_len, 7); + if (copy_result) + copy_result = shadow_copy_sibling (sibling_source, sibling_source_len, ".pdb", sibling_target, sibling_target_len, 11); if (copy_result) copy_result = shadow_copy_sibling (sibling_source, sibling_source_len, ".config", sibling_target, sibling_target_len, 7); @@ -1868,6 +1903,9 @@ mono_make_shadow_copy (const char *filename, MonoError *oerror) } #endif /* DISABLE_SHADOW_COPY */ +/** + * mono_domain_from_appdomain: + */ MonoDomain * mono_domain_from_appdomain (MonoAppDomain *appdomain_raw) { @@ -1996,12 +2034,28 @@ mono_domain_assembly_preload (MonoAssemblyName *aname, set_domain_search_path (domain); + MonoAssemblyCandidatePredicate predicate = NULL; + void* predicate_ud = NULL; +#if !defined(DISABLE_DESKTOP_LOADER) + if (G_LIKELY (mono_loader_get_strict_strong_names ())) { + predicate = &mono_assembly_candidate_predicate_sn_same_name; + predicate_ud = aname; + } +#endif if (domain->search_path && domain->search_path [0] != NULL) { - result = real_load (domain->search_path, aname->culture, aname->name, refonly, NULL, NULL); + if (mono_trace_is_traced (G_LOG_LEVEL_DEBUG, MONO_TRACE_ASSEMBLY)) { + mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_ASSEMBLY, "Domain %s search path is:", domain->friendly_name); + for (int i = 0; domain->search_path [i]; i++) { + const char *p = domain->search_path[i]; + mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_ASSEMBLY, "\tpath[%d] = '%s'", i, p); + } + mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_ASSEMBLY, "End of domain %s search path.", domain->friendly_name); + } + result = real_load (domain->search_path, aname->culture, aname->name, refonly, predicate, predicate_ud); } if (result == NULL && assemblies_path && assemblies_path [0] != NULL) { - result = real_load (assemblies_path, aname->culture, aname->name, refonly, NULL, NULL); + result = real_load (assemblies_path, aname->culture, aname->name, refonly, predicate, predicate_ud); } return result; @@ -2209,11 +2263,8 @@ ves_icall_System_AppDomain_InternalUnload (gint32 domain_id, MonoError *error) * Unloading seems to cause problems when running NUnit/NAnt, hence * this workaround. */ - if (g_getenv ("MONO_NO_UNLOAD")) + if (g_hasenv ("MONO_NO_UNLOAD")) return; -#ifdef __native_client__ - return; -#endif MonoException *exc = NULL; mono_domain_try_unload (domain, (MonoObject**)&exc); @@ -2234,9 +2285,11 @@ ves_icall_System_AppDomain_InternalIsFinalizingForUnload (gint32 domain_id, Mono } void -ves_icall_System_AppDomain_DoUnhandledException (MonoException *exc) +ves_icall_System_AppDomain_DoUnhandledException (MonoExceptionHandle exc, MonoError *error) { - mono_unhandled_exception ((MonoObject*) exc); + error_init (error); + mono_unhandled_exception_checked (MONO_HANDLE_CAST (MonoObject, exc), error); + mono_error_assert_ok (error); } gint32 @@ -2334,24 +2387,27 @@ ves_icall_System_AppDomain_InternalPopDomainRef (MonoError *error) mono_thread_pop_appdomain_ref (); } -MonoAppContext * -ves_icall_System_AppDomain_InternalGetContext () +MonoAppContextHandle +ves_icall_System_AppDomain_InternalGetContext (MonoError *error) { - return mono_context_get (); + error_init (error); + return mono_context_get_handle (); } -MonoAppContext * -ves_icall_System_AppDomain_InternalGetDefaultContext () +MonoAppContextHandle +ves_icall_System_AppDomain_InternalGetDefaultContext (MonoError *error) { - return mono_domain_get ()->default_context; + error_init (error); + return MONO_HANDLE_NEW (MonoAppContext, mono_domain_get ()->default_context); } -MonoAppContext * -ves_icall_System_AppDomain_InternalSetContext (MonoAppContext *mc) +MonoAppContextHandle +ves_icall_System_AppDomain_InternalSetContext (MonoAppContextHandle mc, MonoError *error) { - MonoAppContext *old_context = mono_context_get (); + error_init (error); + MonoAppContextHandle old_context = mono_context_get_handle (); - mono_context_set (mc); + mono_context_set_handle (mc); return old_context; } @@ -2374,6 +2430,9 @@ ves_icall_System_AppDomain_InternalGetProcessGuid (MonoStringHandle newguid, Mon return newguid; } +/** + * mono_domain_is_unloading: + */ gboolean mono_domain_is_unloading (MonoDomain *domain) { @@ -2485,7 +2544,9 @@ unload_thread_main (void *arg) internal = mono_thread_internal_current (); - mono_thread_set_name_internal (internal, mono_string_new (mono_domain_get (), "Domain unloader"), TRUE, FALSE, &error); + MonoString *thread_name_str = mono_string_new_checked (mono_domain_get (), "Domain unloader", &error); + if (is_ok (&error)) + mono_thread_set_name_internal (internal, thread_name_str, TRUE, FALSE, &error); if (!is_ok (&error)) { data->failure_reason = g_strdup (mono_error_get_message (&error)); mono_error_cleanup (&error); @@ -2563,12 +2624,12 @@ failure: return 1; } -/* +/** * mono_domain_unload: - * @domain: The domain to unload + * \param domain The domain to unload * - * Unloads an appdomain. Follows the process outlined in the comment - * for mono_domain_try_unload. + * Unloads an appdomain. Follows the process outlined in the comment + * for \c mono_domain_try_unload. */ void mono_domain_unload (MonoDomain *domain) @@ -2589,10 +2650,10 @@ guarded_wait (MonoThreadHandle *thread_handle, guint32 timeout, gboolean alertab return result; } -/* +/** * mono_domain_unload: - * @domain: The domain to unload - * @exc: Exception information + * \param domain The domain to unload + * \param exc Exception information * * Unloads an appdomain. Follows the process outlined in: * http://blogs.gotdotnet.com/cbrumme