GNOME Bugzilla – Bug 772798
Race condition deadlock in GType initialization
Last modified: 2016-10-12 12:00:35 UTC
There is a race condition when two threads try to initialize a type. Thread A is initializating the gtype, which may involve adding an interface to it. This will grab class_init_rec_mutex. Thread B is inside a class initialization already for some other type, so it already holds class_init_rec_mutex. Then the class init needs the gtype, so it calls get_type() on it. The race here is that A gets to start initialzating the gtype, but before its reached the add_interface call thread B starts the unrelated class init, so thread A is blocking on class_init_rec_mutex. But thread B then blocks in the get_type() waiting for thread B to finish initializating the gtype. So, we deadlock Here is a sample diagram: Thread 1 Thread 2 create GUnixSocketAddress init GUnixSocketAddress type init (parent) GSocketAddress type g_once_init_enter (socket_address_id) Add socket_address_id on g_once_init_list Creating a GSocketClient Needs to initialize GSocketClient class g_type_class_ref (GSocketClient) g_rec_mutex_lock (&class_init_rec_mutex); Call actual GSocketClientClass init code Needs GSocketAddress gtype (for g_signal_new argument) g_socket_address_get_type () g_once_init_enter (socket_address_id) socket_address_id is NULL, so we're not inited but the it is on g_once_init_list! BLOCK until g_once_init_leave for socked_address_id Start initializing GSocketAddress g_type_add_interface_static on socket_address type g_rec_mutex_lock (&class_init_rec_mutex); BLOCKS, because thread 2 is creating a class
Ah, duplicate of #674885. *** This bug has been marked as a duplicate of bug 674885 ***