Hello Muppet! On Tue, 11 Oct 2005 09:34:41 -0400, muppet said:
Congratulations! You've found a reference-handling bug in Glib::Object!
And is that a Good Thing(TM)? ;-) Anyway, thanks for your _very_ exhaustive explanation of what is going on here. [...]
1. gtk_tree_store_new() creates the model with refcount 1. 2. Gtk2::TreeStore::new() takes ownership of that object. refcount is 1, perl wrapper attached and returned as a mortal SV. 3. gtk_tree_view_set_model() adds a ref to the C object. recount is now 2. 4. The temp SV goes out of scope, and Glib::Object::DESTROY swaps its C object reference over to the perl object. C refcount is now 1, held by the TreeView. later: 5. Gtk2::TreeView::get_model() calls gtk_tree_view_get_model(), and finds the model object with refcount 1. 6. Gtk2::TreeView::get_model() calls gperl_get_object() to wrap the C object; it discovers the existing wrapper SV, so returns that. C object reference count is still 1. 7. perl code traps the SV from Gtk2::TreeView::get_model() and SvREFCNT_inc()s it. C object reference count is unchanged. 8. $view->set_model(undef) calls gtk_tree_view_set_model(view, NULL). The treeview sees that it already has a model, so it calls g_object_unref() on it. the model has a C refcount of 1 and an attached SV wrapper with refcount >1. 9. g_object_unref() sees that the model has a C refcount of 1 and that it is releasing the last C reference. ***So, it destroys the object.***
I cannot say that I could follow you into every detail but I think I got the overall picture. [...]
As a workaround, keep your own perl reference to the value returned from Gtk2::TreeStore::new, to prevent Glib::Object::DESTROY from releasing that C reference.
Yep, that works very good. That's the good news of all your hard work. The downside is: I gain only about 2/10 of a second (about 5 %)... I'll have to play a bit more with my code to see where all those processor cycles get used up.
In the example code above, that's as simple as my $view = Gtk2::TreeView->new; # XXX don't let $the_model go out of scope until you're *really* finished with it.
Well, one global variable more or less, who cares... *duck* Ciao Florian
Attachment:
pgpExAmELY9nS.pgp
Description: PGP signature