From 4ee0e5a9846ad5c888246751b7e24f259971d3bd Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Tue, 8 Aug 2023 22:03:52 -0700
Subject: [PATCH] Fixed thread-safety warnings
---
src/joystick/SDL_gamepad.c | 6 ++++++
src/joystick/SDL_joystick.c | 23 ++++++++++++++++++-----
src/joystick/linux/SDL_sysjoystick.c | 4 ++++
3 files changed, 28 insertions(+), 5 deletions(-)
diff --git a/src/joystick/SDL_gamepad.c b/src/joystick/SDL_gamepad.c
index d7fd03d9a3d2..004c647e6ec0 100644
--- a/src/joystick/SDL_gamepad.c
+++ b/src/joystick/SDL_gamepad.c
@@ -362,6 +362,8 @@ void SDL_PrivateGamepadRemoved(SDL_JoystickID instance_id)
SDL_Event event;
SDL_Gamepad *gamepad;
+ SDL_AssertJoysticksLocked();
+
if (!SDL_gamepads_initialized) {
return;
}
@@ -466,6 +468,8 @@ static void AdjustSensorOrientation(SDL_Joystick *joystick, float *src, float *d
{
unsigned int i, j;
+ SDL_AssertJoysticksLocked();
+
for (i = 0; i < 3; ++i) {
dst[i] = 0.0f;
for (j = 0; j < 3; ++j) {
@@ -559,6 +563,8 @@ static SDL_bool HasMappingChangeTracking(MappingChangeTracker *tracker, GamepadM
{
int i;
+ SDL_AssertJoysticksLocked();
+
for (i = 0; i < tracker->num_changed_mappings; ++i) {
if (tracker->changed_mappings[i] == mapping) {
return SDL_TRUE;
diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c
index c69d297b78e8..4b6ff4cf6d4c 100644
--- a/src/joystick/SDL_joystick.c
+++ b/src/joystick/SDL_joystick.c
@@ -150,26 +150,33 @@ void SDL_LockJoysticks(void)
void SDL_UnlockJoysticks(void)
{
- SDL_Mutex *joystick_lock = SDL_joystick_lock;
SDL_bool last_unlock = SDL_FALSE;
--SDL_joysticks_locked;
if (!SDL_joysticks_initialized) {
+ /* NOTE: There's a small window here where another thread could lock the mutex after we've checked for pending locks */
if (!SDL_joysticks_locked && SDL_AtomicGet(&SDL_joystick_lock_pending) == 0) {
- /* NOTE: There's a small window here where another thread could lock the mutex */
- SDL_joystick_lock = NULL;
last_unlock = SDL_TRUE;
}
}
- SDL_UnlockMutex(joystick_lock);
-
/* The last unlock after joysticks are uninitialized will cleanup the mutex,
* allowing applications to lock joysticks while reinitializing the system.
*/
if (last_unlock) {
+ SDL_Mutex *joystick_lock = SDL_joystick_lock;
+
+ SDL_LockMutex(joystick_lock);
+ {
+ SDL_UnlockMutex(SDL_joystick_lock);
+
+ SDL_joystick_lock = NULL;
+ }
+ SDL_UnlockMutex(joystick_lock);
SDL_DestroyMutex(joystick_lock);
+ } else {
+ SDL_UnlockMutex(SDL_joystick_lock);
}
}
@@ -560,6 +567,8 @@ static SDL_bool ShouldAttemptSensorFusion(SDL_Joystick *joystick, SDL_bool *inve
const char *hint;
int hint_value;
+ SDL_AssertJoysticksLocked();
+
*invert_sensors = SDL_FALSE;
/* The SDL controller sensor API is only available for gamepads (at the moment) */
@@ -620,6 +629,8 @@ static void AttemptSensorFusion(SDL_Joystick *joystick, SDL_bool invert_sensors)
SDL_SensorID *sensors;
unsigned int i, j;
+ SDL_AssertJoysticksLocked();
+
if (SDL_InitSubSystem(SDL_INIT_SENSOR) < 0) {
return;
}
@@ -686,6 +697,8 @@ static void AttemptSensorFusion(SDL_Joystick *joystick, SDL_bool invert_sensors)
static void CleanupSensorFusion(SDL_Joystick *joystick)
{
+ SDL_AssertJoysticksLocked();
+
if (joystick->accel_sensor || joystick->gyro_sensor) {
if (joystick->accel_sensor) {
if (joystick->accel) {
diff --git a/src/joystick/linux/SDL_sysjoystick.c b/src/joystick/linux/SDL_sysjoystick.c
index c3d68e1f5052..823a2cbc04f5 100644
--- a/src/joystick/linux/SDL_sysjoystick.c
+++ b/src/joystick/linux/SDL_sysjoystick.c
@@ -1553,6 +1553,8 @@ static int LINUX_JoystickSendEffect(SDL_Joystick *joystick, const void *data, in
static int LINUX_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
{
+ SDL_AssertJoysticksLocked();
+
if (!joystick->hwdata->has_accelerometer && !joystick->hwdata->has_gyro) {
return SDL_Unsupported();
}
@@ -1723,6 +1725,8 @@ static void PollAllSensors(Uint64 timestamp, SDL_Joystick *joystick)
struct input_absinfo absinfo;
int i;
+ SDL_AssertJoysticksLocked();
+
SDL_assert(joystick->hwdata->fd_sensor >= 0);
if (joystick->hwdata->has_gyro) {