>From 50c69aa26e6e2a2000bdca7e4a0a489982dacfbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20Sch=C3=B6nfeld?= Date: Wed, 10 Aug 2011 14:33:23 +0200 Subject: [PATCH] Handle ownership of objects with floating refs correctly Objects with floating refs (for example, GInitiallyUnowned descendants) are created with a floating reference that needs to be "sunk". Enforce this, irregardless of the 'own' setting. The custom converter for GtkObject in Gtk2 already enforces own=1, so this commit does not change anything there. --- GObject.xs | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 47 insertions(+), 0 deletions(-) diff --git a/GObject.xs b/GObject.xs index b5492e4..911d2a2 100644 --- a/GObject.xs +++ b/GObject.xs @@ -925,6 +925,53 @@ gperl_new_object (GObject * object, gperl_object_package_from_type (G_OBJECT_TYPE (object)), SvRV (sv), SvREFCNT (SvRV (sv))); #endif + + /* + * special handling for objects that have a floating ref. there are + * three types of these objects that we can encounter: + * + * A: GInitiallyUnowned descendant, wrapped manually such that always + * own=1, with a custom sink func; prototype: Gtk2::Object + * B: GInitiallyUnowned descendant, wrapped via introspection + * (i.e. always own=0 and no custom sink func); prototype: + * Gtk3::Object + * C: GInitiallyUnowned descendant, wrapped manually, no special own + * handling, no custom sink func; prototype: ? + * + * then, with the code below, we have the following tables of changes + * to object->ref_count: + * + * A own=1 own=0 + * floating=1 ±0 does not + * floating=0 +1 happen + * + * B own=1 own=0 + * floating=1 does not ±0 + * floating=0 happen +1 + * + * C own=1 own=0 + * floating=1 ±0 ±0 + * floating=0 ±0 +1 + */ +#if GLIB_CHECK_VERSION (2, 10, 0) + if (g_object_is_floating (object)) { + /* clear the floating flag. */ + g_object_ref_sink (object); + /* always assume ownership, irregardless of the ownership + * setting that was passed in. this is somewhat of a hack for + * gobject-introspection: it always sets transfer=none for + * GInitiallyUnowned descendants. but Gtk2 effectively does + * exactly the same thing for Gtk2::Object by always passing + * own=1. */ + g_object_unref (object); + /* we have already taken ownership, so don't try to do it + * again. for cases A and B from above, + * gperl_object_take_ownership would do nothing, so this just + * saves a few cycles. but for case C, leaving own=1 would + * result in the object being finalized prematurely. */ + own = FALSE; + } +#endif if (own) gperl_object_take_ownership (object); -- 1.7.4.1