Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRodrigo Kumpera <kumpera@gmail.com>2015-07-20 20:20:56 +0300
committerRodrigo Kumpera <kumpera@gmail.com>2015-07-20 21:23:36 +0300
commit610f14c2472246f38a1d2aded0258fc3ae79437f (patch)
tree024477e2e72594d80e7107e2de7c11c5e9d296ad
parentf160bb5ccc6a039d8a50045fa72f463d60920ca8 (diff)
[runtime] Safe publish MonoImage::name_cache and exploit that around the runtime. Fix ImageLock nested use.
-rw-r--r--mono/metadata/class.c25
1 files changed, 12 insertions, 13 deletions
diff --git a/mono/metadata/class.c b/mono/metadata/class.c
index 321fa2eb848..5ed261ffbbe 100644
--- a/mono/metadata/class.c
+++ b/mono/metadata/class.c
@@ -7462,7 +7462,10 @@ mono_image_init_name_cache (MonoImage *image)
const char *name;
const char *nspace;
guint32 i, visib, nspace_index;
- GHashTable *name_cache2, *nspace_table;
+ GHashTable *name_cache2, *nspace_table, *the_name_cache;
+
+ if (image->name_cache)
+ return;
mono_image_lock (image);
@@ -7471,9 +7474,10 @@ mono_image_init_name_cache (MonoImage *image)
return;
}
- image->name_cache = g_hash_table_new (g_str_hash, g_str_equal);
+ the_name_cache = g_hash_table_new (g_str_hash, g_str_equal);
if (image_is_dynamic (image)) {
+ mono_atomic_store_release (&image->name_cache, the_name_cache);
mono_image_unlock (image);
return;
}
@@ -7497,7 +7501,7 @@ mono_image_init_name_cache (MonoImage *image)
nspace_table = g_hash_table_lookup (name_cache2, GUINT_TO_POINTER (nspace_index));
if (!nspace_table) {
nspace_table = g_hash_table_new (g_str_hash, g_str_equal);
- g_hash_table_insert (image->name_cache, (char*)nspace, nspace_table);
+ g_hash_table_insert (the_name_cache, (char*)nspace, nspace_table);
g_hash_table_insert (name_cache2, GUINT_TO_POINTER (nspace_index),
nspace_table);
}
@@ -7519,7 +7523,7 @@ mono_image_init_name_cache (MonoImage *image)
nspace_table = g_hash_table_lookup (name_cache2, GUINT_TO_POINTER (nspace_index));
if (!nspace_table) {
nspace_table = g_hash_table_new (g_str_hash, g_str_equal);
- g_hash_table_insert (image->name_cache, (char*)nspace, nspace_table);
+ g_hash_table_insert (the_name_cache, (char*)nspace, nspace_table);
g_hash_table_insert (name_cache2, GUINT_TO_POINTER (nspace_index),
nspace_table);
}
@@ -7528,6 +7532,7 @@ mono_image_init_name_cache (MonoImage *image)
}
g_hash_table_destroy (name_cache2);
+ mono_atomic_store_release (&image->name_cache, the_name_cache);
mono_image_unlock (image);
}
@@ -7540,11 +7545,9 @@ mono_image_add_to_name_cache (MonoImage *image, const char *nspace,
GHashTable *name_cache;
guint32 old_index;
+ mono_image_init_name_cache (image);
mono_image_lock (image);
- if (!image->name_cache)
- mono_image_init_name_cache (image);
-
name_cache = image->name_cache;
if (!(nspace_table = g_hash_table_lookup (name_cache, nspace))) {
nspace_table = g_hash_table_new (g_str_hash, g_str_equal);
@@ -7609,11 +7612,9 @@ mono_class_from_name_case_checked (MonoImage *image, const char* name_space, con
guint32 token = 0;
FindUserData user_data;
+ mono_image_init_name_cache (image);
mono_image_lock (image);
- if (!image->name_cache)
- mono_image_init_name_cache (image);
-
user_data.key = name_space;
user_data.value = NULL;
g_hash_table_foreach (image->name_cache, find_nocase, &user_data);
@@ -7753,11 +7754,9 @@ mono_class_from_name_checked_aux (MonoImage *image, const char* name_space, cons
}
}
+ mono_image_init_name_cache (image);
mono_image_lock (image);
- if (!image->name_cache)
- mono_image_init_name_cache (image);
-
nspace_table = g_hash_table_lookup (image->name_cache, name_space);
if (nspace_table)