[gobject-introspection] girepository: Use g_atomic for refcounting
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gobject-introspection] girepository: Use g_atomic for refcounting
- Date: Tue, 2 Apr 2013 17:08:01 +0000 (UTC)
commit 4b1bf70c93acb3446c1e9049ac422d911a10762d
Author: Colin Walters <walters verbum org>
Date: Mon Nov 19 21:42:44 2012 -0500
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 ff9c939..37893e6 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 275776d..bbd34e3 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;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]