From e3e8adcb76f26e9858f0e87a7de89587ada73de0 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Thu, 29 Jan 2026 16:15:37 -0800
Subject: [PATCH] Added SDL_TryLockJoysticks()
---
include/SDL3/SDL_joystick.h | 15 +++++++++++++++
src/dynapi/SDL_dynapi.sym | 1 +
src/dynapi/SDL_dynapi_overrides.h | 1 +
src/dynapi/SDL_dynapi_procs.h | 1 +
src/joystick/SDL_joystick.c | 9 +++++++++
5 files changed, 27 insertions(+)
diff --git a/include/SDL3/SDL_joystick.h b/include/SDL3/SDL_joystick.h
index c93b352107488..74161234bd4e8 100644
--- a/include/SDL3/SDL_joystick.h
+++ b/include/SDL3/SDL_joystick.h
@@ -188,6 +188,21 @@ typedef enum SDL_JoystickConnectionState
*/
extern SDL_DECLSPEC void SDLCALL SDL_LockJoysticks(void) SDL_ACQUIRE(SDL_joystick_lock);
+/**
+ * Locking for atomic access to the joystick API.
+ *
+ * The SDL joystick functions are thread-safe, however you can lock the
+ * joysticks while processing to guarantee that the joystick list won't change
+ * and joystick and gamepad events will not be delivered.
+ *
+ * \returns true if the joysticks were successfully locked, false otherwise.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_TryLockJoysticks(void) SDL_ACQUIRE(SDL_joystick_lock);
+
/**
* Unlocking for atomic access to the joystick API.
*
diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym
index ec2e97beb2edd..2252d31d13c89 100644
--- a/src/dynapi/SDL_dynapi.sym
+++ b/src/dynapi/SDL_dynapi.sym
@@ -1271,6 +1271,7 @@ SDL3_0.0.0 {
SDL_LoadSurface_IO;
SDL_LoadSurface;
SDL_SetWindowFillDocument;
+ SDL_TryLockJoysticks;
# extra symbols go here (don't modify this line)
local: *;
};
diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h
index bf8d64273efa4..d95d3754e7992 100644
--- a/src/dynapi/SDL_dynapi_overrides.h
+++ b/src/dynapi/SDL_dynapi_overrides.h
@@ -1297,3 +1297,4 @@
#define SDL_LoadSurface_IO SDL_LoadSurface_IO_REAL
#define SDL_LoadSurface SDL_LoadSurface_REAL
#define SDL_SetWindowFillDocument SDL_SetWindowFillDocument_REAL
+#define SDL_TryLockJoysticks SDL_TryLockJoysticks_REAL
diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index 9f28b68a50d1f..ee60a4227ddb4 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -1305,3 +1305,4 @@ SDL_DYNAPI_PROC(SDL_Surface*,SDL_RotateSurface,(SDL_Surface *a,float b),(a,b),re
SDL_DYNAPI_PROC(SDL_Surface*,SDL_LoadSurface_IO,(SDL_IOStream *a,bool b),(a,b),return)
SDL_DYNAPI_PROC(SDL_Surface*,SDL_LoadSurface,(const char *a),(a),return)
SDL_DYNAPI_PROC(bool,SDL_SetWindowFillDocument,(SDL_Window *a,bool b),(a,b),return)
+SDL_DYNAPI_PROC(bool,SDL_TryLockJoysticks,(void),(),return)
diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c
index 621adbd3f46f3..c3bfa6b792ef8 100644
--- a/src/joystick/SDL_joystick.c
+++ b/src/joystick/SDL_joystick.c
@@ -653,6 +653,15 @@ void SDL_LockJoysticks(void)
++SDL_joysticks_locked;
}
+bool SDL_TryLockJoysticks(void)
+{
+ if (SDL_TryLockMutex(SDL_joystick_lock)) {
+ ++SDL_joysticks_locked;
+ return true;
+ }
+ return false;
+}
+
void SDL_UnlockJoysticks(void)
{
bool last_unlock = false;