Browse Source

Make sure we hold the joystick lock when disconnecting a HIDAPI joystick

This prevents crashes when calling SDL joystick API functions from a different thread while disconnection is happening.

See https://github.com/libsdl-org/SDL/issues/6063 for a more thorough review of joystick locking.
Sam Lantinga 2 years ago
parent
commit
9670d2bb9e
1 changed files with 11 additions and 13 deletions
  1. 11 13
      src/joystick/hidapi/SDL_hidapijoystick.c

+ 11 - 13
src/joystick/hidapi/SDL_hidapijoystick.c

@@ -522,21 +522,19 @@ void
 HIDAPI_JoystickDisconnected(SDL_HIDAPI_Device *device, SDL_JoystickID joystickID)
 {
     int i, j;
-    SDL_bool unique = HIDAPI_JoystickInstanceIsUnique(device, joystickID);
+   
+    SDL_LockJoysticks();
 
-    if (!unique) {
+    if (!HIDAPI_JoystickInstanceIsUnique(device, joystickID)) {
         /* Disconnecting a child always disconnects the parent */
         device = device->parent;
-        unique = SDL_TRUE;
     }
 
     for (i = 0; i < device->num_joysticks; ++i) {
         if (device->joysticks[i] == joystickID) {
-            if (unique) {
-                SDL_Joystick *joystick = SDL_JoystickFromInstanceID(joystickID);
-                if (joystick) {
-                    HIDAPI_JoystickClose(joystick);
-                }
+            SDL_Joystick *joystick = SDL_JoystickFromInstanceID(joystickID);
+            if (joystick) {
+                HIDAPI_JoystickClose(joystick);
             }
 
             HIDAPI_DelJoystickInstanceFromDevice(device, joystickID);
@@ -546,18 +544,18 @@ HIDAPI_JoystickDisconnected(SDL_HIDAPI_Device *device, SDL_JoystickID joystickID
                 HIDAPI_DelJoystickInstanceFromDevice(child, joystickID);
             }
 
-            if (unique) {
-                --SDL_HIDAPI_numjoysticks;
+            --SDL_HIDAPI_numjoysticks;
 
-                if (!shutting_down) {
-                    SDL_PrivateJoystickRemoved(joystickID);
-                }
+            if (!shutting_down) {
+                SDL_PrivateJoystickRemoved(joystickID);
             }
         }
     }
 
     /* Rescan the device list in case device state has changed */
     SDL_HIDAPI_change_count = 0;
+
+    SDL_UnlockJoysticks();
 }
 
 static int