Browse Source

Fixed thread-safety warnings

Sam Lantinga 1 year ago
parent
commit
4ee0e5a984
3 changed files with 28 additions and 5 deletions
  1. 6 0
      src/joystick/SDL_gamepad.c
  2. 18 5
      src/joystick/SDL_joystick.c
  3. 4 0
      src/joystick/linux/SDL_sysjoystick.c

+ 6 - 0
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;

+ 18 - 5
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) {

+ 4 - 0
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) {