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
This commit is contained in:
Colin Walters 2012-11-19 21:42:44 -05:00
parent 50638cf403
commit 4779b03a21
2 changed files with 19 additions and 15 deletions

View File

@ -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);
}
/**

View File

@ -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;