GNOME Bugzilla – Bug 667424
Add notification before dispose is called
Last modified: 2013-05-10 15:19:31 UTC
I discovered an issue within bug #661456, which provides trace #228750. The thing is that Thread 11 is inside a dispose of an object which is used in Thread 1 of that backtrace. There is no issue with ref counting, the issue is that the thread which runs dispose got interrupted, and the other thread received the object from a cache. The cache removes object only after it's fully finalized, in the callback set on g_object_weak_ref(), but it's too late, because the object already freed half of itself, because of which the application crashed. The closest mechanism is to use toggle_ref-s, but it's not the best thing either, because if more consumers will need to use it, then the object will never be freed. (I'm going to use it for now, but would like to change it when/if this is approved available in GLib.) It seems to me that the best approach would be to provide some callback/signal on GObject, which will be triggered just before the object's dispose method is invoked, thus the caches (yes, there are more involved already) can connect to this callback, instead of the weak_ref, and remove object from its internal structures immediately the dispose process is run. Note this is not only about dispose, I can reproduce this even when finalize callback is "too slow".
We just recently added thread-safe weak references, which should pretty much address this problem. See GWeakRef
Yes, GWeakRef should fix this problem. Thanks for the pointer. Patch in bug 699909.
no bug, then?
(In reply to comment #3) > no bug, then? Well, from my point of view the GWeakRef is not a _notification_, while I ask here for notifications. If I want them, then I'm forced to use both g_object_weak_ref() and GWeakRef together, which is not the same. as a simple notification ala g_object_weak_ref, which will tell me that the object is meant to die, but before the dispose being called.
There is a reason that GWeakRef is threadsafe but cannot send notifications: imagine two people have weak refs. There has to be some _single_ boundary across, once crossed, we consider the object to be dead for everyone. We can (and do) do this by setting everyone's weakref to NULL while holding a lock, for the sake of atomicity. We could not do the same for callbacks -- there would be no notion of atomicity. The first weakref callback would happen and then the second. Maybe the second one even does something stupid like trying to re-ref the object to keep it alive, after we notified the first one. This was an explicit design consideration and this is why it was done that way. Using both mechanisms is, indeed, the correct way.