GVariant: add g_variant_take_ref()

This function implements the following logic:

  if (g_variant_is_floating (value))
    g_variant_ref_sink (value);

which is used for consuming the return value of callbacks that may or
may not return floating references.

This patch also replaces a few instances of the above code with the new
function (GSettings, GDBus) and lifts a long-standing restriction on the
use of floating values as the return value for signal handlers by
improving g_value_take_variant().

https://bugzilla.gnome.org/show_bug.cgi?id=627974
This commit is contained in:
Ryan Lortie
2011-07-11 14:27:53 +02:00
parent 2121e56ea7
commit 58c247e51b
8 changed files with 64 additions and 16 deletions

View File

@@ -1207,11 +1207,9 @@ g_value_set_variant (GValue *value,
* the ownership of the caller's reference to @variant;
* the caller doesn't have to unref it any more (i.e. the reference
* count of the variant is not increased).
*
* It is a programmer error to pass a floating variant to this function.
* In particular this means that callbacks in closures, and signal handlers
* for signals of return type %G_TYPE_VARIANT, must never return floating
* variants.
*
* If @variant was floating then its floating reference is converted to
* a hard reference.
*
* If you want the #GValue to hold its own reference to @variant, use
* g_value_set_variant() instead.
@@ -1227,11 +1225,13 @@ g_value_take_variant (GValue *value,
GVariant *old_variant;
g_return_if_fail (G_VALUE_HOLDS_VARIANT (value));
g_return_if_fail (variant == NULL || !g_variant_is_floating (variant));
old_variant = value->data[0].v_pointer;
value->data[0].v_pointer = variant;
if (variant)
value->data[0].v_pointer = g_variant_take_ref (variant);
else
value->data[0].v_pointer = NULL;
if (old_variant)
g_variant_unref (old_variant);