gi/object: Fix g_weak_ref_get deadlocking if used while GC is running
GObject's weak reference implementation have its own global lock which may result in deadlocking if e.g. another thread calls g_weak_ref_get on a JS-held object while another thread is inside ObjectInstance::disassociate_js_gobject() which eventually leads to the toggle queue being locked by ObjectInstance::wrapped_gobj_toggle_notify() while also holding weak_locations_lock.
Thread 1 | Thread 2
---------------------------------------------------------|--------------------------------------------------------
ObjectInstance::disassociate_js_gobject() |
ToggleQueue::get_default() |
ToggleQueue::lock() |
| g_weak_ref_get()
| g_rw_lock_reader_lock(weak_locations_lock)
| g_object_ref()
| ObjectInstance::wrapped_gobj_toggle_notify()
| ToggleQueue::get_default()
| ToggleQueue::lock()
| (waits for thread 1 to release toggle queue lock)
g_object_weak_unref() |
g_rw_lock_writer_lock(weak_locations_lock) |
(waits for thread 2 to release weak_locations_lock) |
Fix this by releasing the toggle queue lock before calling g_object_weak_unref.
Fixes #558 (closed)