diff options
author | Benjamin Otte <otte@gnome.org> | 2009-09-24 12:26:53 +0200 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2009-11-30 20:52:33 +0100 |
commit | 00a4470ad07551f3629029892b819c18d8902f2f (patch) | |
tree | 3e687ab887b76b344a6e7e5b8cdc99df2a0d03f7 /gobject | |
parent | 4c243b1cba6e94658e68c3e4b188d0d784ed7463 (diff) |
Make ClassData->init_state atomic
This is necessary to make g_type_class_ref() lockless.
https://bugzilla.gnome.org/show_bug.cgi?id=585375
Also includes fix for:
https://bugzilla.gnome.org/show_bug.cgi?id=587892
Diffstat (limited to 'gobject')
-rw-r--r-- | gobject/gtype.c | 24 |
1 files changed, 13 insertions, 11 deletions
diff --git a/gobject/gtype.c b/gobject/gtype.c index af363827c..83e4b1d15 100644 --- a/gobject/gtype.c +++ b/gobject/gtype.c @@ -313,7 +313,7 @@ struct _ClassData { CommonData common; guint16 class_size; - guint init_state : 4; + int volatile init_state; /* atomic - g_type_class_ref reads it unlocked */ GBaseInitFunc class_init_base; GBaseFinalizeFunc class_finalize_base; GClassInitFunc class_init; @@ -326,7 +326,7 @@ struct _InstanceData { CommonData common; guint16 class_size; - guint init_state : 4; + int volatile init_state; /* atomic - g_type_class_ref reads it unlocked */ GBaseInitFunc class_init_base; GBaseFinalizeFunc class_finalize_base; GClassInitFunc class_init; @@ -2057,7 +2057,7 @@ type_class_init_Wm (TypeNode *node, class = g_malloc0 (node->data->class.class_size); node->data->class.class = class; - node->data->class.init_state = BASE_CLASS_INIT; + g_atomic_int_set (&node->data->class.init_state, BASE_CLASS_INIT); if (pclass) { @@ -2094,7 +2094,7 @@ type_class_init_Wm (TypeNode *node, G_WRITE_LOCK (&type_rw_lock); - node->data->class.init_state = BASE_IFACE_INIT; + g_atomic_int_set (&node->data->class.init_state, BASE_IFACE_INIT); /* Before we initialize the class, base initialize all interfaces, either * from parent, or through our holder info @@ -2150,7 +2150,7 @@ type_class_init_Wm (TypeNode *node, i++; } - node->data->class.init_state = CLASS_INIT; + g_atomic_int_set (&node->data->class.init_state, CLASS_INIT); G_WRITE_UNLOCK (&type_rw_lock); @@ -2159,7 +2159,7 @@ type_class_init_Wm (TypeNode *node, G_WRITE_LOCK (&type_rw_lock); - node->data->class.init_state = IFACE_INIT; + g_atomic_int_set (&node->data->class.init_state, IFACE_INIT); /* finish initializing the interfaces through our holder info. * inherited interfaces are already init_state == INITIALIZED, because @@ -2190,7 +2190,7 @@ type_class_init_Wm (TypeNode *node, i++; } - node->data->class.init_state = INITIALIZED; + g_atomic_int_set (&node->data->class.init_state, INITIALIZED); } static void @@ -2821,8 +2821,7 @@ g_type_class_ref (GType type) G_WRITE_LOCK (&type_rw_lock); node = lookup_type_node_I (type); if (node && node->is_classed && node->data && - node->data->class.class && - node->data->class.init_state == INITIALIZED) + g_atomic_int_get (&node->data->class.init_state) == INITIALIZED) { type_data_ref_Wm (node); G_WRITE_UNLOCK (&type_rw_lock); @@ -2933,7 +2932,9 @@ g_type_class_peek (GType type) node = lookup_type_node_I (type); G_READ_LOCK (&type_rw_lock); - if (node && node->is_classed && node->data && node->data->class.class) /* ref_count _may_ be 0 */ + if (node && node->is_classed && node->data && + g_atomic_int_get (&node->data->class.init_state) == INITIALIZED) + /* ref_count _may_ be 0 */ class = node->data->class.class; else class = NULL; @@ -2963,7 +2964,8 @@ g_type_class_peek_static (GType type) G_READ_LOCK (&type_rw_lock); if (node && node->is_classed && node->data && /* peek only static types: */ node->plugin == NULL && - node->data->class.class) /* ref_count _may_ be 0 */ + g_atomic_int_get (&node->data->class.init_state) == INITIALIZED) + /* ref_count _may_ be 0 */ class = node->data->class.class; else class = NULL; |