mono_os_mutex_init_recursive (&set->lock);
for (i = 0; i < nimages; ++i)
set->images [i] = images [i];
- set->gclass_cache = g_hash_table_new_full (mono_generic_class_hash, mono_generic_class_equal, NULL, (GDestroyNotify)free_generic_class);
+ set->gclass_cache = mono_conc_hashtable_new_full (mono_generic_class_hash, mono_generic_class_equal, NULL, (GDestroyNotify)free_generic_class);
set->ginst_cache = g_hash_table_new_full (mono_metadata_generic_inst_hash, mono_metadata_generic_inst_equal, NULL, (GDestroyNotify)free_generic_inst);
set->gmethod_cache = g_hash_table_new_full (inflated_method_hash, inflated_method_equal, NULL, (GDestroyNotify)free_inflated_method);
set->gsignature_cache = g_hash_table_new_full (inflated_signature_hash, inflated_signature_equal, NULL, (GDestroyNotify)free_inflated_signature);
{
int i;
- g_hash_table_destroy (set->gclass_cache);
+ mono_conc_hashtable_destroy (set->gclass_cache);
g_hash_table_destroy (set->ginst_cache);
g_hash_table_destroy (set->gmethod_cache);
g_hash_table_destroy (set->gsignature_cache);
MonoImageSet *set = (MonoImageSet *)l->data;
mono_image_set_lock (set);
- g_hash_table_foreach_steal (set->gclass_cache, steal_gclass_in_image, &gclass_data);
+ mono_conc_hashtable_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);
collect_data_free (&data);
- mono_image_set_lock (set);
-
- gclass = (MonoGenericClass *)g_hash_table_lookup (set->gclass_cache, &helper);
+ gclass = (MonoGenericClass *)mono_conc_hashtable_lookup (set->gclass_cache, &helper);
/* A tripwire just to keep us honest */
g_assert (!helper.cached_class);
- if (gclass) {
- mono_image_set_unlock (set);
+ if (gclass)
return gclass;
- }
gclass = mono_image_set_new0 (set, MonoGenericClass, 1);
if (is_dynamic)
if (inst == mono_class_get_generic_container (container_class)->context.class_inst && !is_tb_open)
gclass->cached_class = container_class;
- g_hash_table_insert (set->gclass_cache, gclass, gclass);
+ mono_image_set_lock (set);
+
+ MonoGenericClass *gclass2 = mono_conc_hashtable_insert (set->gclass_cache, gclass, gclass);
+ if (!gclass2)
+ gclass2 = gclass;
+
+ // g_hash_table_insert (set->gclass_cache, gclass, gclass);
mono_image_set_unlock (set);
- return gclass;
+ return gclass2;
}
/*
kvs [i].value = NULL;
mono_memory_barrier ();
kvs [i].key = TOMBSTONE;
+ --hash_table->element_count;
if (hash_table->key_destroy_func != NULL)
(*hash_table->key_destroy_func) (key);
}
}
}
+
+/**
+ * mono_conc_hashtable_foreach_steal:
+ *
+ * Calls @func for each entry in the hashtable, if @func returns true, remove from the hashtable. Requires external locking.
+ * Same semantics as g_hash_table_foreach_steal.
+ */
+void
+mono_conc_hashtable_foreach_steal (MonoConcurrentHashTable *hash_table, GHRFunc func, gpointer userdata)
+{
+ int i;
+ conc_table *table = (conc_table*)hash_table->table;
+ key_value_pair *kvs = table->kvs;
+
+ for (i = 0; i < table->table_size; ++i) {
+ if (kvs [i].key && kvs [i].key != TOMBSTONE) {
+ if (func (kvs [i].key, kvs [i].value, userdata)) {
+ kvs [i].value = NULL;
+ mono_memory_barrier ();
+ kvs [i].key = TOMBSTONE;
+ --hash_table->element_count;
+ }
+ }
+ }
+}