Re: Speedup insert into treestore



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



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]