From: Edward Hervey Date: Thu, 24 Sep 2009 09:45:13 +0000 (+0200) Subject: Make type_data_unref_U not take locks in the common case X-Git-Tag: 2.23.1~34 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4c243b1cba6e94658e68c3e4b188d0d784ed7463;p=platform%2Fupstream%2Fglib.git Make type_data_unref_U not take locks in the common case https://bugzilla.gnome.org/show_bug.cgi?id=585375 --- diff --git a/gobject/gtype.c b/gobject/gtype.c index 2a4925c..af36382 100644 --- a/gobject/gtype.c +++ b/gobject/gtype.c @@ -2346,11 +2346,12 @@ static inline void type_data_unref_U (TypeNode *node, gboolean uncached) { - G_WRITE_LOCK (&type_rw_lock); - g_assert (node->data && NODE_REFCOUNT (node) > 0); - if (NODE_REFCOUNT (node) > 1) - g_atomic_int_add ((int *) &node->ref_count, -1); - else + guint current; + + do { + current = NODE_REFCOUNT (node); + + if (current <= 1) { if (!node->plugin) { @@ -2358,13 +2359,17 @@ type_data_unref_U (TypeNode *node, NODE_NAME (node)); return; } - G_WRITE_UNLOCK (&type_rw_lock); + + g_assert (current > 0); + g_static_rec_mutex_lock (&class_init_rec_mutex); /* required locking order: 1) class_init_rec_mutex, 2) type_rw_lock */ G_WRITE_LOCK (&type_rw_lock); type_data_last_unref_Wm (node, uncached); + G_WRITE_UNLOCK (&type_rw_lock); g_static_rec_mutex_unlock (&class_init_rec_mutex); + return; } - G_WRITE_UNLOCK (&type_rw_lock); + } while (!g_atomic_int_compare_and_exchange ((int *) &node->ref_count, current, current - 1)); } /**