On 11.11.2013 01:09, Kevin Ryde wrote: > How has this bit gone? It definitely seems to do something unexpectedly > bad. How would you feel about reverting until the reason can be found?
I've had another look at this and now think that I understand what is going on: Your MyContainer class derives from Gtk2::HBox and so, by extension, from Glib::InitiallyUnowned. The GObject underlying the instance created by libgobject thus has only a single, floating reference. When marshalling this object for INIT_INSTANCE, another reference is added, but the existing reference is kept in the floating state (due to own=FALSE in the gperl_new_object() call in gperl_type_instance_init()). Without the call to $label->parent, this additional reference is simply removed when INIT_INSTANCE exits (with the change under discussion) or sometime later (without it), and the original floating reference remains. It later gets sunk in the marshalling of the MyContainer->new call. If you do, however, call $label->parent, then the marshalling code sees that the underlying GObject has a floating reference and takes over ownership of it (without adding a new reference). The GObject now has two references to it, one from $self and one from $parent. With the change under discussion, both of these get removed when INIT_INSTANCE exits, leading to the destruction of the GObject. Without the change, the removal of the reference from $self to the GObject is delayed until after the MyContainer->new call returned and $mycontainer added another reference, thus preventing the destruction of the GObject. So at this point, reverting the change (as in the attached patch) does seem like a sensible thing to do. This comes with a cost, however; for example, Glib::Object::Introspection's test suite breaks. So I have to ask: why are you calling $label->parent in INIT_INSTANCE instead of simply using $self?
>From f46253bdb981eb569daeea93f43efcdc6db0c70b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20Sch=C3=B6nfeld?= <kaffeeti...@gmx.de> Date: Sun, 24 Nov 2013 21:45:45 +0100 Subject: [PATCH] WIP --- GType.xs | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/GType.xs b/GType.xs index 471a4ee..dc0b3d9 100644 --- a/GType.xs +++ b/GType.xs @@ -1756,8 +1756,28 @@ gperl_type_instance_init (GObject * instance) SV **slot; g_assert (stash != NULL); - /* this SV will be freed below either via sv_2mortal or explicitly. */ - obj = gperl_new_object (instance, FALSE); + /* we need to always create a wrapper, regardless of whether there is + * an INIT_INSTANCE sub. otherwise, the fallback mechanism in + * GType.xs' SET_PROPERTY handler will not have an HV to store the + * properties in. + * + * we also need to ensure that the wrapper we create is not immediately + * destroyed when we return from gperl_type_instance_init. otherwise, + * instances of classes derived from GInitiallyUnowned might be + * destroyed prematurely when code in INIT_INSTANCE manages to sink the + * initial, floating reference. example: in a container subclass' + * INIT_INSTANCE, adding a child and then calling the child's + * get_parent() method. so we mortalize the wrapper before the + * SAVETMPS/FREETMPS pair below. this should ensure that the wrapper + * survives long enough so that it is still intact when the call to the + * Perl constructor returns. + * + * if we always sank floating references, or if we forbade doing things + * as described in the example, we could simply free the SV before we + * return from gperl_type_instance_init. this would result in more + * predictable reference counting. */ + obj = sv_2mortal (gperl_new_object (instance, FALSE)); + /* we need to re-bless the wrapper because classes change * during construction of an object. */ sv_bless (obj, stash); @@ -1776,13 +1796,11 @@ gperl_type_instance_init (GObject * instance) ENTER; SAVETMPS; PUSHMARK (SP); - XPUSHs (sv_2mortal (obj)); /* mortalize the SV */ + XPUSHs (obj); PUTBACK; call_sv ((SV *)GvCV (*slot), G_VOID|G_DISCARD); FREETMPS; LEAVE; - } else { - SvREFCNT_dec (obj); /* free the SV explicitly */ } } -- 1.8.1.2
_______________________________________________ gtk-perl-list mailing list gtk-perl-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-perl-list