After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 772798 - Race condition deadlock in GType initialization
Race condition deadlock in GType initialization
Status: RESOLVED DUPLICATE of bug 674885
Product: glib
Classification: Platform
Component: gobject
unspecified
Other Linux
: Normal normal
: ---
Assigned To: gtkdev
gtkdev
Depends on:
Blocks:
 
 
Reported: 2016-10-12 11:58 UTC by Alexander Larsson
Modified: 2016-10-12 12:00 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Alexander Larsson 2016-10-12 11:58:08 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
Comment 1 Alexander Larsson 2016-10-12 12:00:35 UTC
Ah, duplicate of #674885.

*** This bug has been marked as a duplicate of bug 674885 ***