|
Lines 2363-2382
gpointer
Link Here
|
| 2363 |
g_type_class_ref (GType type) |
2363 |
g_type_class_ref (GType type) |
| 2364 |
{ |
2364 |
{ |
| 2365 |
TypeNode *node; |
2365 |
TypeNode *node; |
| 2366 |
|
2366 |
GType ptype; |
| 2367 |
/* optimize for common code path |
2367 |
|
| 2368 |
*/ |
2368 |
/* optimize for common code path */ |
| 2369 |
G_WRITE_LOCK (&type_rw_lock); |
2369 |
G_WRITE_LOCK (&type_rw_lock); |
| 2370 |
node = lookup_type_node_I (type); |
2370 |
node = lookup_type_node_I (type); |
| 2371 |
if (node && node->is_classed && node->data && |
2371 |
if (node && node->is_classed && node->data && |
| 2372 |
node->data->class.class && node->data->common.ref_count > 0) |
2372 |
node->data->class.class && |
|
|
2373 |
node->data->class.init_state == INITIALIZED) |
| 2373 |
{ |
2374 |
{ |
| 2374 |
type_data_ref_Wm (node); |
2375 |
type_data_ref_Wm (node); |
| 2375 |
G_WRITE_UNLOCK (&type_rw_lock); |
2376 |
G_WRITE_UNLOCK (&type_rw_lock); |
| 2376 |
|
|
|
| 2377 |
return node->data->class.class; |
2377 |
return node->data->class.class; |
| 2378 |
} |
2378 |
} |
| 2379 |
|
|
|
| 2380 |
if (!node || !node->is_classed || |
2379 |
if (!node || !node->is_classed || |
| 2381 |
(node->data && node->data->common.ref_count < 1)) |
2380 |
(node->data && node->data->common.ref_count < 1)) |
| 2382 |
{ |
2381 |
{ |
|
Lines 2385-2417
g_type_class_ref (GType type)
Link Here
|
| 2385 |
type_descriptive_name_I (type)); |
2384 |
type_descriptive_name_I (type)); |
| 2386 |
return NULL; |
2385 |
return NULL; |
| 2387 |
} |
2386 |
} |
| 2388 |
|
|
|
| 2389 |
type_data_ref_Wm (node); |
2387 |
type_data_ref_Wm (node); |
|
|
2388 |
ptype = NODE_PARENT_TYPE (node); |
| 2389 |
G_WRITE_UNLOCK (&type_rw_lock); |
| 2390 |
|
2390 |
|
|
|
2391 |
g_static_rec_mutex_lock (&class_init_rec_mutex); /* required locking order: 1) class_init_rec_mutex, 2) type_rw_lock */ |
| 2392 |
/* here, we either have node->data->class.class == NULL, or |
| 2393 |
* node->data->class.init_state == INITIALIZED, because any |
| 2394 |
* concurrently running initialization was guarded by class_init_rec_mutex. |
| 2395 |
*/ |
| 2391 |
if (!node->data->class.class) /* class uninitialized */ |
2396 |
if (!node->data->class.class) /* class uninitialized */ |
| 2392 |
{ |
2397 |
{ |
| 2393 |
GType ptype = NODE_PARENT_TYPE (node); |
2398 |
/* acquire reference on parent class */ |
| 2394 |
GTypeClass *pclass = NULL; |
2399 |
GTypeClass *pclass = ptype ? g_type_class_ref (ptype) : NULL; |
| 2395 |
G_WRITE_UNLOCK (&type_rw_lock); |
2400 |
G_WRITE_LOCK (&type_rw_lock); |
| 2396 |
g_static_rec_mutex_lock (&class_init_rec_mutex); /* required locking order: 1) class_init_rec_mutex, 2) type_rw_lock */ |
2401 |
if (node->data->class.class) /* class was initialized during parent class initialization? */ |
| 2397 |
if (ptype) |
2402 |
INVALID_RECURSION ("g_type_plugin_*", node->plugin, NODE_NAME (node)); |
| 2398 |
{ |
2403 |
type_class_init_Wm (node, pclass); |
| 2399 |
pclass = g_type_class_ref (ptype); |
|
|
| 2400 |
G_WRITE_LOCK (&type_rw_lock); |
| 2401 |
node = lookup_type_node_I (type); |
| 2402 |
if (node->data->class.class) |
| 2403 |
INVALID_RECURSION ("g_type_plugin_*", node->plugin, NODE_NAME (node)); |
| 2404 |
} |
| 2405 |
else |
| 2406 |
{ |
| 2407 |
G_WRITE_LOCK (&type_rw_lock); |
| 2408 |
node = lookup_type_node_I (type); |
| 2409 |
} |
| 2410 |
if (!node->data->class.class) /* class could have been initialized meanwhile */ |
| 2411 |
type_class_init_Wm (node, pclass); |
| 2412 |
G_WRITE_UNLOCK (&type_rw_lock); |
2404 |
G_WRITE_UNLOCK (&type_rw_lock); |
| 2413 |
g_static_rec_mutex_unlock (&class_init_rec_mutex); |
|
|
| 2414 |
} |
2405 |
} |
|
|
2406 |
g_static_rec_mutex_unlock (&class_init_rec_mutex); |
| 2407 |
|
| 2415 |
return node->data->class.class; |
2408 |
return node->data->class.class; |
| 2416 |
} |
2409 |
} |
| 2417 |
|
2410 |
|
| 2418 |
- |
|
|
| 2419 |
* tests/threadtests.c: added race condition tester from Michael Meeks |
2411 |
* tests/threadtests.c: added race condition tester from Michael Meeks |
| 2420 |
with a couple fixes so it's not triggering development warnings. From: |
2412 |
with a couple fixes so it's not triggering development warnings. From: |
| 2421 |
Bug 537555 - GObject instantiation not thread safe ... |
2413 |
Bug 537555 - GObject instantiation not thread safe ... |
| 2422 |
-- |
|
|
| 2423 |
gobject/ChangeLog | 6 +++ |
2414 |
gobject/ChangeLog | 6 +++ |
| 2424 |
gobject/tests/threadtests.c | 75 ++++++++++++++++++++++++++++++++++++++++++- |
2415 |
gobject/tests/threadtests.c | 75 ++++++++++++++++++++++++++++++++++++++++++- |
| 2425 |
2 files changed, 80 insertions(+), 1 deletions(-) |
2416 |
2 files changed, 80 insertions(+), 1 deletions(-) |