Enable thread-safety features in libdbus
authorSam Lantinga
Mon, 30 Mar 2020 14:26:15 -0700
changeset 13681e078c7e21285
parent 13680 6ef67a58efb4
child 13682 bd45c7649f7b
Enable thread-safety features in libdbus

There are multiple SDL APIs that internally sink into dbus calls, e.g. battery
status, thread priority. If those calls happen in different threads simultaneously
it can result in dbus crashes.

To abide by dbus's multithreading guidelines we must call dbus_threads_init_default()
to enable dbus's internal locking mechanisms:
https://dbus.freedesktop.org/doc/api/html/group__DBusThreads.html#gac7b8a7001befc3eaa8c6b043151008dc

Additionally, access to a DBusMessage must be synchronized between threads.
SDL was already abiding that guideline as the DBusMessage structs aren't shared.

The following email from the dbus mailing list hints that arbitrating access to
the DBusConnection on the SDL may also be required:
https://lists.freedesktop.org/archives/dbus/2017-September/017306.html
src/core/linux/SDL_dbus.c
src/core/linux/SDL_dbus.h
     1.1 --- a/src/core/linux/SDL_dbus.c	Mon Mar 30 14:26:10 2020 -0700
     1.2 +++ b/src/core/linux/SDL_dbus.c	Mon Mar 30 14:26:15 2020 -0700
     1.3 @@ -65,6 +65,7 @@
     1.4      SDL_DBUS_SYM(message_iter_get_arg_type);
     1.5      SDL_DBUS_SYM(message_iter_recurse);
     1.6      SDL_DBUS_SYM(message_unref);
     1.7 +    SDL_DBUS_SYM(threads_init_default);
     1.8      SDL_DBUS_SYM(error_init);
     1.9      SDL_DBUS_SYM(error_is_set);
    1.10      SDL_DBUS_SYM(error_free);
    1.11 @@ -124,6 +125,11 @@
    1.12              return;  /* oh well */
    1.13          }
    1.14  
    1.15 +        if (!dbus.threads_init_default()) {
    1.16 +            is_dbus_available = SDL_FALSE;
    1.17 +            return;
    1.18 +        }
    1.19 +
    1.20          dbus.error_init(&err);
    1.21          /* session bus is required */
    1.22  
     2.1 --- a/src/core/linux/SDL_dbus.h	Mon Mar 30 14:26:10 2020 -0700
     2.2 +++ b/src/core/linux/SDL_dbus.h	Mon Mar 30 14:26:15 2020 -0700
     2.3 @@ -62,6 +62,7 @@
     2.4      int (*message_iter_get_arg_type)(DBusMessageIter *);
     2.5      void (*message_iter_recurse)(DBusMessageIter *, DBusMessageIter *); 
     2.6      void (*message_unref)(DBusMessage *);
     2.7 +    dbus_bool_t (*threads_init_default)(void);
     2.8      void (*error_init)(DBusError *);
     2.9      dbus_bool_t (*error_is_set)(const DBusError *);
    2.10      void (*error_free)(DBusError *);