Re: Problems with signals and object destruction



On Apr 19, 2007, at 8:37 PM, Daniel Kasak wrote:


Anyway, I'm going to *great* lengths to track all the signals I connect,
and disconnect them when closing down ( honest ). And yet object
destruction still doesn't work.


This sort of gymnastics should not be necessary. GObject will destroy all of its signal handlers in the base GObject::dispose() method (part of the destruction process), and Glib::Object connects those with closures so that we get proper destruction notification for cleaning up the callback subroutine and user data references. With that, and reference counting everywhere, everything should Just Work.

The situations you want to watch out for are:

- Any form of circular reference.  Avoid keeping references to yourself.
- Take care with closures, and they can hide references to objects and create reference cycles. - NEVER override DESTROY on a Glib::Object, or you will break object destruction. (This is documented in the Glib::Object::Subclass manpage.)

For things that are necessary reference cycles, your basic hammer for that nail is the GtkObject's "destroy" signal, where you can delete things that don't clean up nicely. But, for the most part, since the bindings take care to make sure that all perl objects are held in such a way that references are released at the right time, this is rarely a problem. (In fact, although i've had to deal with this before, i can't clearly remember the situations.)



Is there a way I can list all signals connected to an object?


From looking at the gobject source:  You can:

- list the signals of a type or instance (g_signal_list_ids(), Glib::Type::list_signals()) - ask whether a particular instance has any handlers connected to a particular signal (g_signal_has_handler_pending(), not bound to perl) - ask for the first handler connected to a signal on an instance (g_signal_handler_find(), not bound to perl, mostly because of heavy magic requirement to implement) - block, unblock, and disconnect a given handler or handlers that match in name, callback, and data (several functions, look for "by_func" in Glib::Object)

but as far as i can tell, there is no way to list all of the handlers connected to a signal. And, really, you shouldn't need to.



Am I correct in assuming that it's my inability to cleanly destroy stuff
that's leading to crashes? Or maybe I'm exposing a Windows-only bug?


I'm not convinced it's a cleanup issue, since a) it's supposed to Just Work, and, b) as you say, it manifests only on windows.

Now, can you *verify* that this stuff doesn't happen on windows? Try running your app under valgrind on linux, and watch for any bad accesses. Linux is often a little bit more forgiving about such things than windows.



--
I hate to break it to you, but magic data pixies don't exist.
  -- Simon Cozens




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