mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-12-06 16:44:51 +01:00
fixed race condition where references to partially initialized classes
2008-06-10 13:15:29 Tim Janik <timj@imendio.com> * gtype.c (g_type_class_ref): fixed race condition where references to partially initialized classes could be handed out. svn path=/trunk/; revision=6982
This commit is contained in:
committed by
Tim Janik
parent
b15a223a8a
commit
e9f756f17e
@@ -1,3 +1,8 @@
|
|||||||
|
2008-06-10 13:15:29 Tim Janik <timj@imendio.com>
|
||||||
|
|
||||||
|
* gtype.c (g_type_class_ref): fixed race condition where references to
|
||||||
|
partially initialized classes could be handed out.
|
||||||
|
|
||||||
2008-05-28 Michael Natterer <mitch@imendio.com>
|
2008-05-28 Michael Natterer <mitch@imendio.com>
|
||||||
|
|
||||||
* Makefile.am: don't define G_DISABLE_SINGLE_INCLUDES, it's in
|
* Makefile.am: don't define G_DISABLE_SINGLE_INCLUDES, it's in
|
||||||
|
|||||||
@@ -2363,20 +2363,19 @@ gpointer
|
|||||||
g_type_class_ref (GType type)
|
g_type_class_ref (GType type)
|
||||||
{
|
{
|
||||||
TypeNode *node;
|
TypeNode *node;
|
||||||
|
GType ptype;
|
||||||
|
|
||||||
/* optimize for common code path
|
/* optimize for common code path */
|
||||||
*/
|
|
||||||
G_WRITE_LOCK (&type_rw_lock);
|
G_WRITE_LOCK (&type_rw_lock);
|
||||||
node = lookup_type_node_I (type);
|
node = lookup_type_node_I (type);
|
||||||
if (node && node->is_classed && node->data &&
|
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);
|
type_data_ref_Wm (node);
|
||||||
G_WRITE_UNLOCK (&type_rw_lock);
|
G_WRITE_UNLOCK (&type_rw_lock);
|
||||||
|
|
||||||
return node->data->class.class;
|
return node->data->class.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!node || !node->is_classed ||
|
if (!node || !node->is_classed ||
|
||||||
(node->data && node->data->common.ref_count < 1))
|
(node->data && node->data->common.ref_count < 1))
|
||||||
{
|
{
|
||||||
@@ -2385,33 +2384,27 @@ g_type_class_ref (GType type)
|
|||||||
type_descriptive_name_I (type));
|
type_descriptive_name_I (type));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
type_data_ref_Wm (node);
|
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
|
||||||
|
* 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 */
|
if (!node->data->class.class) /* class uninitialized */
|
||||||
{
|
{
|
||||||
GType ptype = NODE_PARENT_TYPE (node);
|
/* acquire reference on parent class */
|
||||||
GTypeClass *pclass = NULL;
|
GTypeClass *pclass = ptype ? g_type_class_ref (ptype) : 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);
|
G_WRITE_LOCK (&type_rw_lock);
|
||||||
node = lookup_type_node_I (type);
|
if (node->data->class.class) /* class was initialized during parent class initialization? */
|
||||||
if (node->data->class.class)
|
|
||||||
INVALID_RECURSION ("g_type_plugin_*", node->plugin, NODE_NAME (node));
|
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);
|
type_class_init_Wm (node, pclass);
|
||||||
G_WRITE_UNLOCK (&type_rw_lock);
|
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;
|
return node->data->class.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user