SDL: dbus: Wrap init in a spinlock.

From d483970262e32ca7b3a376e538f454d8a1f1ec6d Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Wed, 4 Aug 2021 13:30:12 -0400
Subject: [PATCH] dbus: Wrap init in a spinlock.

This prevents a race if two threads that need d-bus try to init it at the
same time. Note that SDL_Init will likely handle this from a single thread
at startup, but there are places outside of init where one might trigger
D-Bus init, like setting thread priority (a common first thing for a new
thread to do) resulting in SDL trying to use RTKit.

Fixes #4587.
---
 src/core/linux/SDL_dbus.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/src/core/linux/SDL_dbus.c b/src/core/linux/SDL_dbus.c
index 9b22f789f..e83da80c7 100644
--- a/src/core/linux/SDL_dbus.c
+++ b/src/core/linux/SDL_dbus.c
@@ -20,6 +20,7 @@
 */
 #include "../../SDL_internal.h"
 #include "SDL_dbus.h"
+#include "SDL_atomic.h"
 
 #if SDL_USE_LIBDBUS
 /* we never link directly to libdbus. */
@@ -113,8 +114,12 @@ LoadDBUSLibrary(void)
     return retval;
 }
 
-void
-SDL_DBus_Init(void)
+
+static SDL_SpinLock spinlock_dbus_init = 0;
+
+/* you must hold spinlock_dbus_init before calling this! */
+static void
+SDL_DBus_Init_Spinlocked(void)
 {
     static SDL_bool is_dbus_available = SDL_TRUE;
     if (!is_dbus_available) {
@@ -156,6 +161,14 @@ SDL_DBus_Init(void)
     }
 }
 
+void
+SDL_DBus_Init(void)
+{
+    SDL_AtomicLock(&spinlock_dbus_init);  /* make sure two threads can't init at same time, since this can happen before SDL_Init. */
+    SDL_DBus_Init_Spinlocked();
+    SDL_AtomicUnlock(&spinlock_dbus_init);
+}
+
 void
 SDL_DBus_Quit(void)
 {