From 4b1bf70c93acb3446c1e9049ac422d911a10762d Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 19 Nov 2012 21:42:44 -0500 Subject: girepository: Use g_atomic for refcounting They could be freed in separate threads (e.g. language binding GC thread). But no particular reason to change other than noticing it during code inspection for a different bug. https://bugzilla.gnome.org/show_bug.cgi?id=688694 --- girepository/gibaseinfo.c | 25 ++++++++++++------------- girepository/girepository-private.h | 9 +++++++-- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/girepository/gibaseinfo.c b/girepository/gibaseinfo.c index ff9c9395..37893e6c 100644 --- a/girepository/gibaseinfo.c +++ b/girepository/gibaseinfo.c @@ -226,7 +226,7 @@ g_base_info_ref (GIBaseInfo *info) GIRealInfo *rinfo = (GIRealInfo*)info; g_assert (rinfo->ref_count != INVALID_REFCOUNT); - ((GIRealInfo*)info)->ref_count++; + g_atomic_int_inc (&rinfo->ref_count); return info; } @@ -244,21 +244,20 @@ g_base_info_unref (GIBaseInfo *info) GIRealInfo *rinfo = (GIRealInfo*)info; g_assert (rinfo->ref_count > 0 && rinfo->ref_count != INVALID_REFCOUNT); - rinfo->ref_count--; - if (!rinfo->ref_count) - { - if (rinfo->container && ((GIRealInfo *) rinfo->container)->ref_count != INVALID_REFCOUNT) - g_base_info_unref (rinfo->container); + if (!g_atomic_int_dec_and_test (&rinfo->ref_count)) + return; - if (rinfo->repository) - g_object_unref (rinfo->repository); + if (rinfo->container && ((GIRealInfo *) rinfo->container)->ref_count != INVALID_REFCOUNT) + g_base_info_unref (rinfo->container); - if (rinfo->type == GI_INFO_TYPE_UNRESOLVED) - g_slice_free (GIUnresolvedInfo, (GIUnresolvedInfo *) rinfo); - else - g_slice_free (GIRealInfo, rinfo); - } + if (rinfo->repository) + g_object_unref (rinfo->repository); + + if (rinfo->type == GI_INFO_TYPE_UNRESOLVED) + g_slice_free (GIUnresolvedInfo, (GIUnresolvedInfo *) rinfo); + else + g_slice_free (GIRealInfo, rinfo); } /** diff --git a/girepository/girepository-private.h b/girepository/girepository-private.h index 275776d8..bbd34e3e 100644 --- a/girepository/girepository-private.h +++ b/girepository/girepository-private.h @@ -33,6 +33,11 @@ typedef struct _GIRealInfo GIRealInfo; +/* We changed a gint32 -> gint in the structure below, which should be + * valid everywhere we care about. + */ +G_STATIC_ASSERT (sizeof (int) == sizeof (gint32)); + /* * We just use one structure for all of the info object * types; in general, we should be reading data directly @@ -43,7 +48,7 @@ struct _GIRealInfo { /* Keep this part in sync with GIUnresolvedInfo below */ gint32 type; - gint32 ref_count; + volatile gint ref_count; GIRepository *repository; GIBaseInfo *container; @@ -62,7 +67,7 @@ struct _GIUnresolvedInfo { /* Keep this part in sync with GIBaseInfo above */ gint32 type; - gint32 ref_count; + volatile gint ref_count; GIRepository *repository; GIBaseInfo *container; -- cgit v1.2.1