[glib: 1/2] GObject: add g_object_take_ref()
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib: 1/2] GObject: add g_object_take_ref()
- Date: Tue, 15 Jun 2021 11:28:01 +0000 (UTC)
commit 3764c6730eeb5cb5a11968c48251b8bfac9617a2
Author: Allison Ryan Lortie <desrt desrt ca>
Date: Thu Jun 10 10:26:41 2021 +0530
GObject: add g_object_take_ref()
This works in the same way as g_variant_take_ref(), and for the same
reason.
Updated and Rebased by Nitin Wartkar <nitinwartkar58 gmail com>
Closes #1112
docs/reference/gobject/gobject-sections.txt | 1 +
gobject/gobject.c | 56 +++++++++++++++++++++++++++++
gobject/gobject.h | 2 ++
gobject/tests/reference.c | 14 ++++++++
4 files changed, 73 insertions(+)
---
diff --git a/docs/reference/gobject/gobject-sections.txt b/docs/reference/gobject/gobject-sections.txt
index bc8e0c7fb..685529708 100644
--- a/docs/reference/gobject/gobject-sections.txt
+++ b/docs/reference/gobject/gobject-sections.txt
@@ -268,6 +268,7 @@ GParameter
g_object_ref
g_object_unref
g_object_ref_sink
+g_object_take_ref
g_set_object
g_clear_object
GInitiallyUnowned
diff --git a/gobject/gobject.c b/gobject/gobject.c
index 2346cb3ef..a88682360 100644
--- a/gobject/gobject.c
+++ b/gobject/gobject.c
@@ -3185,6 +3185,62 @@ gpointer
return object;
}
+/**
+ * g_object_take_ref: (skip)
+ * @object: (type GObject.Object): a #GObject
+ *
+ * If @object is floating, sink it. Otherwise, do nothing.
+ *
+ * In other words, this function will convert a floating reference (if
+ * present) into a full reference.
+ *
+ * Typically you want to use g_object_ref_sink() in order to
+ * automatically do the correct thing with respect to floating or
+ * non-floating references, but there is one specific scenario where
+ * this function is helpful.
+ *
+ * The situation where this function is helpful is when creating an API
+ * that allows the user to provide a callback function that returns a
+ * GObject. We certainly want to allow the user the flexibility to
+ * return a non-floating reference from this callback (for the case
+ * where the object that is being returned already exists).
+ *
+ * At the same time, the API style of some popular GObject-based
+ * libraries (such as Gtk) make it likely that for newly-created GObject
+ * instances, the user can be saved some typing if they are allowed to
+ * return a floating reference.
+ *
+ * Using this function on the return value of the user's callback allows
+ * the user to do whichever is more convenient for them. The caller will
+ * alway receives exactly one full reference to the value: either the
+ * one that was returned in the first place, or a floating reference
+ * that has been converted to a full reference.
+ *
+ * This function has an odd interaction when combined with
+ * g_object_ref_sink() running at the same time in another thread on
+ * the same #GObject instance. If g_object_ref_sink() runs first then
+ * the result will be that the floating reference is converted to a hard
+ * reference. If g_object_take_ref() runs first then the result will be
+ * that the floating reference is converted to a hard reference and an
+ * additional reference on top of that one is added. It is best to avoid
+ * this situation.
+ *
+ * Since: 2.70
+ *
+ * Returns: (type GObject.Object) (transfer full): @object
+ */
+gpointer
+g_object_take_ref (gpointer _object)
+{
+ GObject *object = _object;
+ g_return_val_if_fail (G_IS_OBJECT (object), object);
+ g_return_val_if_fail (g_atomic_int_get (&object->ref_count) >= 1, object);
+
+ floating_flag_handler (object, -1);
+
+ return object;
+}
+
/**
* g_object_force_floating:
* @object: a #GObject
diff --git a/gobject/gobject.h b/gobject/gobject.h
index 125aed876..f11ea5e76 100644
--- a/gobject/gobject.h
+++ b/gobject/gobject.h
@@ -499,6 +499,8 @@ GLIB_AVAILABLE_IN_ALL
gboolean g_object_is_floating (gpointer object);
GLIB_AVAILABLE_IN_ALL
gpointer g_object_ref_sink (gpointer object);
+GLIB_AVAILABLE_IN_2_70
+gpointer g_object_take_ref (gpointer object);
GLIB_AVAILABLE_IN_ALL
gpointer g_object_ref (gpointer object);
GLIB_AVAILABLE_IN_ALL
diff --git a/gobject/tests/reference.c b/gobject/tests/reference.c
index c6f4d5127..04645e14a 100644
--- a/gobject/tests/reference.c
+++ b/gobject/tests/reference.c
@@ -322,6 +322,20 @@ test_initially_unowned (void)
g_object_ref_sink (obj);
g_object_unref (obj);
+
+ obj = g_object_new (G_TYPE_INITIALLY_UNOWNED, NULL);
+ g_assert_true (g_object_is_floating (obj));
+ g_assert_cmpint (obj->ref_count, ==, 1);
+
+ g_object_take_ref (obj);
+ g_assert_false (g_object_is_floating (obj));
+ g_assert_cmpint (obj->ref_count, ==, 1);
+
+ g_object_take_ref (obj);
+ g_assert_false (g_object_is_floating (obj));
+ g_assert_cmpint (obj->ref_count, ==, 1);
+
+ g_object_unref (obj);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]