diff --git a/include/SDL_hints.h b/include/SDL_hints.h index d78659bf2..db4fc2313 100644 --- a/include/SDL_hints.h +++ b/include/SDL_hints.h @@ -2666,6 +2666,22 @@ extern "C" { */ #define SDL_HINT_TRACKPAD_IS_TOUCH_ONLY "SDL_TRACKPAD_IS_TOUCH_ONLY" +/** + * Let SDL handle dbus_shutdown(). + * + * Only enable this option if no other dependency uses D-Bus. + * + * This option tells SDL that it can safely call dbus_shutdown() when + * SDL_Quit() is called. You must ensure that no other library still uses + * D-Bus when SDL_Quit() is called, otherwise resources will be freed while + * they are still in use, which results in undefined behavior and likely a + * crash. + * + * Use this option to prevent memory leaks if your application doesn't use + * D-Bus other than through SDL. + */ +#define SDL_HINT_SHUTDOWN_DBUS_ON_QUIT "SDL_SHUTDOWN_DBUS_ON_QUIT" + /** * \brief An enumeration of hint priorities diff --git a/src/SDL.c b/src/SDL.c index c52f89972..7065fe711 100644 --- a/src/SDL.c +++ b/src/SDL.c @@ -508,13 +508,13 @@ void SDL_Quit(void) SDL_TicksQuit(); #endif - SDL_ClearHints(); - SDL_AssertionsQuit(); - #ifdef SDL_USE_LIBDBUS SDL_DBus_Quit(); #endif + SDL_ClearHints(); + SDL_AssertionsQuit(); + SDL_LogQuit(); /* Now that every subsystem has been quit, we reset the subsystem refcount diff --git a/src/core/linux/SDL_dbus.c b/src/core/linux/SDL_dbus.c index b14cc26cb..4a9f39718 100644 --- a/src/core/linux/SDL_dbus.c +++ b/src/core/linux/SDL_dbus.c @@ -186,14 +186,12 @@ void SDL_DBus_Quit(void) dbus.connection_close(dbus.session_conn); dbus.connection_unref(dbus.session_conn); } -/* Don't do this - bug 3950 - dbus_shutdown() is a debug feature which closes all global resources in the dbus library. Calling this should be done by the app, not a library, because if there are multiple users of dbus in the process then SDL could shut it down even though another part is using it. -*/ -#if 0 - if (dbus.shutdown) { + + SDL_bool q = SDL_GetHintBoolean(SDL_HINT_SHUTDOWN_DBUS_ON_QUIT, SDL_FALSE); + if (q == SDL_TRUE && dbus.shutdown) { dbus.shutdown(); } -#endif + SDL_zero(dbus); UnloadDBUSLibrary(); SDL_free(inhibit_handle);