glib r7054 - branches/glib-2-16/gobject
- From: matthiasc svn gnome org
- To: svn-commits-list gnome org
- Subject: glib r7054 - branches/glib-2-16/gobject
- Date: Tue, 17 Jun 2008 02:58:11 +0000 (UTC)
Author: matthiasc
Date: Tue Jun 17 02:58:11 2008
New Revision: 7054
URL: http://svn.gnome.org/viewvc/glib?rev=7054&view=rev
Log:
* gtype.c (g_type_class_ref): fixed race condition where references to
partially initialized classes could be handed out.
Modified:
branches/glib-2-16/gobject/ChangeLog
branches/glib-2-16/gobject/gtype.c
Modified: branches/glib-2-16/gobject/gtype.c
==============================================================================
--- branches/glib-2-16/gobject/gtype.c (original)
+++ branches/glib-2-16/gobject/gtype.c Tue Jun 17 02:58:11 2008
@@ -2363,20 +2363,19 @@
g_type_class_ref (GType type)
{
TypeNode *node;
-
- /* optimize for common code path
- */
+ GType ptype;
+
+ /* optimize for common code path */
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->common.ref_count > 0)
+ node->data->class.class &&
+ node->data->class.init_state == INITIALIZED)
{
type_data_ref_Wm (node);
G_WRITE_UNLOCK (&type_rw_lock);
-
return node->data->class.class;
}
-
if (!node || !node->is_classed ||
(node->data && node->data->common.ref_count < 1))
{
@@ -2385,33 +2384,28 @@
type_descriptive_name_I (type));
return NULL;
}
-
type_data_ref_Wm (node);
+ ptype = NODE_PARENT_TYPE (node);
+ G_WRITE_UNLOCK (&type_rw_lock);
+ g_static_rec_mutex_lock (&class_init_rec_mutex); /* required locking order: 1) class_init_rec_mutex, 2) type_rw_lock */
+ /* here, we either have node->data->class.class == NULL, or a recursive
+ * call to g_type_class_ref() with a partly initialized class, or
+ * node->data->class.init_state == INITIALIZED, because any
+ * concurrently running initialization was guarded by class_init_rec_mutex.
+ */
if (!node->data->class.class) /* class uninitialized */
{
- GType ptype = NODE_PARENT_TYPE (node);
- GTypeClass *pclass = NULL;
- G_WRITE_UNLOCK (&type_rw_lock);
- g_static_rec_mutex_lock (&class_init_rec_mutex); /* required locking order: 1) class_init_rec_mutex, 2) type_rw_lock */
- if (ptype)
- {
- pclass = g_type_class_ref (ptype);
- G_WRITE_LOCK (&type_rw_lock);
- node = lookup_type_node_I (type);
- if (node->data->class.class)
- INVALID_RECURSION ("g_type_plugin_*", node->plugin, NODE_NAME (node));
- }
- else
- {
- G_WRITE_LOCK (&type_rw_lock);
- node = lookup_type_node_I (type);
- }
- if (!node->data->class.class) /* class could have been initialized meanwhile */
- type_class_init_Wm (node, pclass);
+ /* acquire reference on parent class */
+ GTypeClass *pclass = ptype ? g_type_class_ref (ptype) : NULL;
+ G_WRITE_LOCK (&type_rw_lock);
+ if (node->data->class.class) /* class was initialized during parent class initialization? */
+ INVALID_RECURSION ("g_type_plugin_*", node->plugin, NODE_NAME (node));
+ type_class_init_Wm (node, pclass);
G_WRITE_UNLOCK (&type_rw_lock);
- g_static_rec_mutex_unlock (&class_init_rec_mutex);
}
+ g_static_rec_mutex_unlock (&class_init_rec_mutex);
+
return node->data->class.class;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]