From 8c4e4d57b3cf2ec3ee5ff8e30b0816141cf733bd Mon Sep 17 00:00:00 2001
From: Semphris <[EMAIL REDACTED]>
Date: Tue, 2 Jan 2024 13:15:32 -0500
Subject: [PATCH] Add hint to make SDL handle dbus_shutdown()
(cherry picked from commit 2348e8b6a2598af2790937a62ee49cdb02d6bd28)
---
include/SDL_hints.h | 16 ++++++++++++++++
src/SDL.c | 6 +++---
src/core/linux/SDL_dbus.c | 10 ++++------
3 files changed, 23 insertions(+), 9 deletions(-)
diff --git a/include/SDL_hints.h b/include/SDL_hints.h
index d78659bf2ce3..db4fc2313f7f 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 c52f89972e72..7065fe711616 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 b14cc26cb05a..4a9f397184fc 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);