Skip to content

Commit

Permalink
Enable thread-safety features in libdbus
Browse files Browse the repository at this point in the history
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
  • Loading branch information
slouken committed Mar 30, 2020
1 parent 2e667a8 commit f4a56d7
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/core/linux/SDL_dbus.c
Expand Up @@ -65,6 +65,7 @@ LoadDBUSSyms(void)
SDL_DBUS_SYM(message_iter_get_arg_type);
SDL_DBUS_SYM(message_iter_recurse);
SDL_DBUS_SYM(message_unref);
SDL_DBUS_SYM(threads_init_default);
SDL_DBUS_SYM(error_init);
SDL_DBUS_SYM(error_is_set);
SDL_DBUS_SYM(error_free);
Expand Down Expand Up @@ -124,6 +125,11 @@ SDL_DBus_Init(void)
return; /* oh well */
}

if (!dbus.threads_init_default()) {
is_dbus_available = SDL_FALSE;
return;
}

dbus.error_init(&err);
/* session bus is required */

Expand Down
1 change: 1 addition & 0 deletions src/core/linux/SDL_dbus.h
Expand Up @@ -62,6 +62,7 @@ typedef struct SDL_DBusContext {
int (*message_iter_get_arg_type)(DBusMessageIter *);
void (*message_iter_recurse)(DBusMessageIter *, DBusMessageIter *);
void (*message_unref)(DBusMessage *);
dbus_bool_t (*threads_init_default)(void);
void (*error_init)(DBusError *);
dbus_bool_t (*error_is_set)(const DBusError *);
void (*error_free)(DBusError *);
Expand Down

0 comments on commit f4a56d7

Please sign in to comment.