I've been working on an object that processes data using background threads. I've come to a bit of a problem with reference counting, if the objects reference count reaches zero, I want the threads to abort after finishing the current item. To do this, I have a flag in the object which is checked before processing each item, when it is set to TRUE by the objects dispose function, the threads abort. The problem with this is that the object gets destroyed while the threads are still using it. It makes sense that the threads should hold a reference to the object that they're using, but then the object is holding a reference to itself and will never be freed. One solution to this is to set the flag and then wait for all the threads in the dispose function. The easiest way to do this seems to be to use a read-write lock and read-lock it during each thread, and then write-lock it in the dispose method. Unfortunately, this causes g_object_unref to hang until all the threads finish, which might not be desirable. The other idea I had was to add a weak reference to the object for each thread and then have the notify function add a strong reference. This way, the objects dispose function is called which toggles the flag, but the finalize function is prevented because the object gets referenced. When each thread aborts, they can unref the object again which will eventually trigger the finalize function. I think this way will work, but it seems kind of ugly. Can anyone suggest a better way to do this? If not, would it be worth adding something to glib to handle cases like this? Perhaps something like g_object_thread_ref(GObject *object) and then have a callback for when the normal reference count drops to zero but wait for the thread reference count to drop to zero before actually calling dispose and finalize?
Attachment:
pgpBPtVMs6I4y.pgp
Description: PGP signature