X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Floader.c;h=d2136bbfc6419667341cf5066afe5afd7140a877;hb=761a84f867fb747fdb49ef0e9338284e70caec32;hp=2c591c9e4f910177930f9c84dd38ea95e6dc659d;hpb=6caa50dedb98c62abe42132ae57f94f4b99e5340;p=mono.git diff --git a/mono/metadata/loader.c b/mono/metadata/loader.c index 2c591c9e4f9..d2136bbfc64 100644 --- a/mono/metadata/loader.c +++ b/mono/metadata/loader.c @@ -39,12 +39,13 @@ #include #include #include -#include +#include #include #include #include #include #include +#include MonoDefaults mono_defaults; @@ -55,7 +56,8 @@ MonoDefaults mono_defaults; * See domain-internals.h for locking policy in combination with the * domain lock. */ -static mono_mutex_t loader_mutex, global_loader_data_mutex; +static MonoCoopMutex loader_mutex; +static mono_mutex_t global_loader_data_mutex; static gboolean loader_lock_inited; /* Statistics */ @@ -81,13 +83,13 @@ static void dllmap_cleanup (void); static void global_loader_data_lock (void) { - mono_locks_acquire (&global_loader_data_mutex, LoaderGlobalDataLock); + mono_locks_os_acquire (&global_loader_data_mutex, LoaderGlobalDataLock); } static void global_loader_data_unlock (void) { - mono_locks_release (&global_loader_data_mutex, LoaderGlobalDataLock); + mono_locks_os_release (&global_loader_data_mutex, LoaderGlobalDataLock); } void @@ -96,8 +98,8 @@ mono_loader_init () static gboolean inited; if (!inited) { - mono_mutex_init_recursive (&loader_mutex); - mono_mutex_init_recursive (&global_loader_data_mutex); + mono_coop_mutex_init_recursive (&loader_mutex); + mono_os_mutex_init_recursive (&global_loader_data_mutex); loader_lock_inited = TRUE; mono_native_tls_alloc (&loader_error_thread_id, NULL); @@ -125,8 +127,8 @@ mono_loader_cleanup (void) mono_native_tls_free (loader_error_thread_id); mono_native_tls_free (loader_lock_nest_id); - mono_mutex_destroy (&loader_mutex); - mono_mutex_destroy (&global_loader_data_mutex); + mono_coop_mutex_destroy (&loader_mutex); + mono_os_mutex_destroy (&global_loader_data_mutex); loader_lock_inited = FALSE; } @@ -600,8 +602,11 @@ mono_field_from_token_checked (MonoImage *image, guint32 token, MonoClass **retk } } - if (field && field->parent && !field->parent->generic_class && !field->parent->generic_container) + if (field && field->parent && !field->parent->generic_class && !field->parent->generic_container) { + mono_image_lock (image); mono_conc_hashtable_insert (image->field_cache, GUINT_TO_POINTER (token), field); + mono_image_unlock (image); + } mono_loader_assert_no_error (); return field; @@ -1192,12 +1197,9 @@ method_from_methodspec (MonoImage *image, MonoGenericContext *context, guint32 i ptr++; param_count = mono_metadata_decode_value (ptr, &ptr); - inst = mono_metadata_parse_generic_inst (image, NULL, param_count, ptr, &ptr); - if (!inst) { - mono_loader_assert_no_error (); - mono_error_set_bad_image (error, image, "Cannot parse generic instance for methodspec 0x%08x", idx); + inst = mono_metadata_parse_generic_inst (image, NULL, param_count, ptr, &ptr, error); + if (!inst) return NULL; - } if (context && inst->is_open) { inst = mono_metadata_inflate_generic_inst (inst, context, error); @@ -1428,7 +1430,7 @@ mono_lookup_pinvoke_call (MonoMethod *method, const char **exc_class, const char const char *new_scope; char *error_msg; char *full_name, *file_name, *found_name = NULL; - int i; + int i,j; MonoDl *module = NULL; gboolean cached = FALSE; @@ -1576,23 +1578,85 @@ mono_lookup_pinvoke_call (MonoMethod *method, const char **exc_class, const char } if (!module && !is_absolute) { - void *iter = NULL; - char *mdirname = g_path_get_dirname (image->name); - while ((full_name = mono_dl_build_path (mdirname, file_name, &iter))) { - module = cached_module_load (full_name, MONO_DL_LAZY, &error_msg); - if (!module) { - mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_DLLIMPORT, - "DllImport error loading library '%s': '%s'.", - full_name, error_msg); - g_free (error_msg); - } else { - found_name = g_strdup (full_name); + void *iter; + char *mdirname; + + for (j = 0; j < 3; ++j) { + iter = NULL; + mdirname = NULL; + switch (j) { + case 0: + mdirname = g_path_get_dirname (image->name); + break; + case 1: /* @executable_path@/../lib */ + { + char buf [4096]; + int binl; + binl = mono_dl_get_executable_path (buf, sizeof (buf)); + if (binl != -1) { + char *base, *newbase; + char *resolvedname; + buf [binl] = 0; + resolvedname = mono_path_resolve_symlinks (buf); + + base = g_path_get_dirname (resolvedname); + newbase = g_path_get_dirname(base); + mdirname = g_strdup_printf ("%s/lib", newbase); + + g_free (resolvedname); + g_free (base); + g_free (newbase); + } + break; + } +#ifdef __MACH__ + case 2: /* @executable_path@/../Libraries */ + { + char buf [4096]; + int binl; + binl = mono_dl_get_executable_path (buf, sizeof (buf)); + if (binl != -1) { + char *base, *newbase; + char *resolvedname; + buf [binl] = 0; + resolvedname = mono_path_resolve_symlinks (buf); + + base = g_path_get_dirname (resolvedname); + newbase = g_path_get_dirname(base); + mdirname = g_strdup_printf ("%s/Libraries", newbase); + + g_free (resolvedname); + g_free (base); + g_free (newbase); + } + break; + } +#endif } - g_free (full_name); + + if (!mdirname) + continue; + + while ((full_name = mono_dl_build_path (mdirname, file_name, &iter))) { + module = cached_module_load (full_name, MONO_DL_LAZY, &error_msg); + if (!module) { + mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_DLLIMPORT, + "DllImport error loading library '%s': '%s'.", + full_name, error_msg); + g_free (error_msg); + } else { + found_name = g_strdup (full_name); + } + g_free (full_name); + if (module) + break; + + } + g_free (mdirname); if (module) break; } - g_free (mdirname); + } if (!module) { @@ -1879,6 +1943,7 @@ mono_get_method_from_token (MonoImage *image, guint32 token, MonoClass *klass, if (generic_container) { result->is_generic = TRUE; generic_container->owner.method = result; + generic_container->is_anonymous = FALSE; // Method is now known, container is no longer anonymous /*FIXME put this before the image alloc*/ if (!mono_metadata_load_generic_param_constraints_checked (image, token, generic_container, error)) return NULL; @@ -2477,10 +2542,7 @@ static gboolean loader_lock_track_ownership = FALSE; void mono_loader_lock (void) { - MONO_TRY_BLOCKING; - mono_locks_acquire (&loader_mutex, LoaderLock); - MONO_FINISH_TRY_BLOCKING; - + mono_locks_coop_acquire (&loader_mutex, LoaderLock); if (G_UNLIKELY (loader_lock_track_ownership)) { mono_native_tls_set_value (loader_lock_nest_id, GUINT_TO_POINTER (GPOINTER_TO_UINT (mono_native_tls_get_value (loader_lock_nest_id)) + 1)); } @@ -2489,7 +2551,7 @@ mono_loader_lock (void) void mono_loader_unlock (void) { - mono_locks_release (&loader_mutex, LoaderLock); + mono_locks_coop_release (&loader_mutex, LoaderLock); if (G_UNLIKELY (loader_lock_track_ownership)) { mono_native_tls_set_value (loader_lock_nest_id, GUINT_TO_POINTER (GPOINTER_TO_UINT (mono_native_tls_get_value (loader_lock_nest_id)) - 1)); }