Re: how to use set_threadsafe

zentara said:
The warning I get is:
GLib-CRITICAL **: g_hash_table_foreach: assertion `hash_table != NULL' failed
at ./basic-thread-test line 23.

This is not actually from the set_threadsafe() call.

You didn't post enough code for me to make a certain declaration of what's
happening, but i have a theory.

The set_threadsafe() XSUB merely sets a flag and returns; if object tracking
was enabled at compile time, it returns the value you set, if not, it always
returns false.  That's why i know it's not from your set_threadsafe call ---
it simply can't be.  The message you're seeing comes from GLib itself (note
the "GLib-CRITICAL" and "g_hash_table_foreach"), so it's a problem with our
code passing NULL somewhere.

The point of the object tracking stuff is to have Glib::Object keep hash of
all objects you've created, so that when the interpreter gets CLONEd, it can
properly ref each object --- otherwise, the objects tend to disappear out from
under you in the main thread when the child thread dies.  It does this by
adding the pointer to each object wrapped by gperl_object_new() to a private
global GHashTable in GObject.xs.  In Glib::Object::CLONE, we then call
g_hash_table_foreach() on that table ("perl_gobjects") and ref everything in

However, in Glib::Object::CLONE, we don't check that perl_gobjects is non-null
before passing it to g_hash_table_foreach().  The hash table is created if it
doesn't exist in gperl_object_new().

So, you're turning on threadsafety object tracking and then proceeding to
create your thread before creating any GObjects (that go all the way to perl).

To fix it for yourself until the fix is reviewed and lands in CVS[*], try this

Index: GObject.xs
RCS file: /cvsroot/gtk2-perl/gtk2-perl-xs/Glib/GObject.xs,v
retrieving revision 1.52
diff -u -r1.52 GObject.xs
--- GObject.xs  13 Nov 2005 16:43:43 -0000      1.52
+++ GObject.xs  18 Nov 2005 18:33:15 -0000
@@ -882,7 +882,9 @@
 CLONE (gchar * class)
-       if (perl_gobject_tracking && strcmp (class, "Glib::Object") == 0)
+       if (perl_gobject_tracking &&
+           perl_gobjects &&  /* nothing to do if we haven't wrapped any */
+           strcmp (class, "Glib::Object") == 0)
                G_LOCK (perl_gobjects);
 /*g_printerr ("we're in clone: %s\n", class);*/

A similar problem could manifest in Glib::Object::DESTROY, but by a different
path (e.g. creating objects before enabling object tracking).  Not sure of the
proper fix for that.

[*] I will be away from email (visiting family out of town) from tomorrow
until the end of the month.

muppet <scott at asofyet dot org>

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