static GHashTable *type_cache = NULL;
static int next_generic_inst_id = 0;
+/* Protected by image_sets_mutex */
static MonoImageSet *mscorlib_image_set;
+/* Protected by image_sets_mutex */
static GPtrArray *image_sets;
+static CRITICAL_SECTION image_sets_mutex;
static guint mono_generic_class_hash (gconstpointer data);
for (i = 0; i < NBUILTIN_TYPES (); ++i)
g_hash_table_insert (type_cache, (gpointer) &builtin_types [i], (gpointer) &builtin_types [i]);
+
+ InitializeCriticalSection (&image_sets_mutex);
}
/**
type_cache = NULL;
g_ptr_array_free (image_sets, TRUE);
image_sets = NULL;
+ DeleteCriticalSection (&image_sets_mutex);
}
/**
}
}
+static inline void
+image_sets_lock (void)
+{
+ EnterCriticalSection (&image_sets_mutex);
+}
+
+static inline void
+image_sets_unlock (void)
+{
+ LeaveCriticalSection (&image_sets_mutex);
+}
+
/*
* get_image_set:
*
* Return a MonoImageSet representing the set of images in IMAGES.
- *
- * LOCKING: Assumes the loader lock is held.
*/
static MonoImageSet*
get_image_set (MonoImage **images, int nimages)
MonoImageSet *set;
GSList *l;
- if (!image_sets)
- image_sets = g_ptr_array_new ();
-
/* Common case */
if (nimages == 1 && images [0] == mono_defaults.corlib && mscorlib_image_set)
return mscorlib_image_set;
if (nimages == 0)
return mscorlib_image_set;
+ image_sets_lock ();
+
+ if (!image_sets)
+ image_sets = g_ptr_array_new ();
+
if (images [0] == mono_defaults.corlib && nimages > 1)
l = images [1]->image_sets;
else
g_ptr_array_add (image_sets, set);
}
- if (nimages == 1 && images [0] == mono_defaults.corlib)
+ if (nimages == 1 && images [0] == mono_defaults.corlib) {
+ mono_memory_barrier ();
mscorlib_image_set = set;
+ }
+
+ image_sets_unlock ();
return set;
}
g_hash_table_destroy (set->gmethod_cache);
g_hash_table_destroy (set->gsignature_cache);
+ image_sets_lock ();
+
for (i = 0; i < set->nimages; ++i)
set->images [i]->image_sets = g_slist_remove (set->images [i]->image_sets, set);
g_ptr_array_remove (image_sets, set);
+ image_sets_unlock ();
+
if (set->mempool)
mono_mempool_destroy (set->mempool);
g_free (set->images);
for (l = image->image_sets; l; l = l->next) {
MonoImageSet *set = l->data;
+ mono_image_set_lock (set);
g_hash_table_foreach_steal (set->gclass_cache, steal_gclass_in_image, &gclass_data);
g_hash_table_foreach_steal (set->ginst_cache, steal_ginst_in_image, &ginst_data);
g_hash_table_foreach_remove (set->gmethod_cache, inflated_method_in_image, image);
g_hash_table_foreach_remove (set->gsignature_cache, inflated_signature_in_image, image);
+ mono_image_set_unlock (set);
}
/* Delete the removed items */
{
CollectData data;
MonoImageSet *set;
+ gpointer res;
collect_data_init (&data);
collect_data_free (&data);
if (cache) {
+ mono_image_set_lock (set);
g_hash_table_insert (set->gmethod_cache, method, method);
+ mono_image_set_unlock (set);
return method;
} else {
- return g_hash_table_lookup (set->gmethod_cache, method);
+ mono_image_set_lock (set);
+ res = g_hash_table_lookup (set->gmethod_cache, method);
+ mono_image_set_unlock (set);
+
+ return res;
}
}
CollectData data;
MonoImageSet *set;
- mono_loader_lock ();
-
helper.sig = sig;
helper.context.class_inst = context->class_inst;
helper.context.method_inst = context->method_inst;
collect_data_free (&data);
+ mono_image_set_lock (set);
+
res = g_hash_table_lookup (set->gsignature_cache, &helper);
if (!res) {
res = g_new0 (MonoInflatedMethodSignature, 1);
g_hash_table_insert (set->gsignature_cache, res, res);
}
- mono_loader_unlock ();
+ mono_image_set_unlock (set);
+
return res->sig;
}
ginst->type_argc = type_argc;
memcpy (ginst->type_argv, type_argv, type_argc * sizeof (MonoType *));
- mono_loader_lock ();
-
collect_data_init (&data);
collect_ginst_images (ginst, &data);
collect_data_free (&data);
+ mono_image_set_lock (set);
+
ginst = g_hash_table_lookup (set->ginst_cache, ginst);
if (!ginst) {
ginst = mono_image_set_alloc0 (set, size);
g_hash_table_insert (set->ginst_cache, ginst, ginst);
}
- mono_loader_unlock ();
+ mono_image_set_unlock (set);
return ginst;
}
helper.is_tb_open = is_tb_open;
helper.cached_class = NULL;
- mono_loader_lock ();
-
collect_data_init (&data);
collect_gclass_images (&helper, &data);
collect_data_free (&data);
+ mono_image_set_lock (set);
+
gclass = g_hash_table_lookup (set->gclass_cache, &helper);
/* A tripwire just to keep us honest */
g_assert (!helper.cached_class);
if (gclass) {
- mono_loader_unlock ();
+ mono_image_set_unlock (set);
return gclass;
}
g_hash_table_insert (set->gclass_cache, gclass, gclass);
- mono_loader_unlock ();
+ mono_image_set_unlock (set);
return gclass;
}