mirror of
				https://gitlab.gnome.org/GNOME/glib.git
				synced 2025-11-03 17:48:56 +01: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:
		@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -494,6 +494,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
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user