mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-04-01 13:23:07 +02:00
Merge branch 'g_obj_take_ref' into 'main'
GObject: add g_object_take_ref() Closes #1112 See merge request GNOME/glib!2146
This commit is contained in:
commit
b95d9d1db6
@ -268,6 +268,7 @@ GParameter
|
|||||||
g_object_ref
|
g_object_ref
|
||||||
g_object_unref
|
g_object_unref
|
||||||
g_object_ref_sink
|
g_object_ref_sink
|
||||||
|
g_object_take_ref
|
||||||
g_set_object
|
g_set_object
|
||||||
g_clear_object
|
g_clear_object
|
||||||
GInitiallyUnowned
|
GInitiallyUnowned
|
||||||
|
@ -3185,6 +3185,62 @@ gpointer
|
|||||||
return object;
|
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:
|
* g_object_force_floating:
|
||||||
* @object: a #GObject
|
* @object: a #GObject
|
||||||
|
@ -494,6 +494,8 @@ GLIB_AVAILABLE_IN_ALL
|
|||||||
gboolean g_object_is_floating (gpointer object);
|
gboolean g_object_is_floating (gpointer object);
|
||||||
GLIB_AVAILABLE_IN_ALL
|
GLIB_AVAILABLE_IN_ALL
|
||||||
gpointer g_object_ref_sink (gpointer object);
|
gpointer g_object_ref_sink (gpointer object);
|
||||||
|
GLIB_AVAILABLE_IN_2_70
|
||||||
|
gpointer g_object_take_ref (gpointer object);
|
||||||
GLIB_AVAILABLE_IN_ALL
|
GLIB_AVAILABLE_IN_ALL
|
||||||
gpointer g_object_ref (gpointer object);
|
gpointer g_object_ref (gpointer object);
|
||||||
GLIB_AVAILABLE_IN_ALL
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
@ -322,6 +322,20 @@ test_initially_unowned (void)
|
|||||||
|
|
||||||
g_object_ref_sink (obj);
|
g_object_ref_sink (obj);
|
||||||
g_object_unref (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
|
static void
|
||||||
|
Loading…
x
Reference in New Issue
Block a user