Sfoglia il codice sorgente

Eliminate contention between HIDAPI controller reads and writes

Rumble can often take a long time, and it is theoretically safe to simultaneously read and write hidapi devices on all platforms.

Fixes https://github.com/libsdl-org/SDL/issues/9441
Sam Lantinga 3 settimane fa
parent
commit
71f4af7322

+ 0 - 2
src/joystick/hidapi/SDL_hidapi_rumble.c

@@ -77,14 +77,12 @@ static int SDLCALL SDL_HIDAPI_RumbleThread(void *data)
         SDL_UnlockMutex(SDL_HIDAPI_rumble_lock);
 
         if (request) {
-            SDL_LockMutex(request->device->dev_lock);
             if (request->device->dev) {
 #ifdef DEBUG_RUMBLE
                 HIDAPI_DumpPacket("Rumble packet: size = %d", request->data, request->size);
 #endif
                 SDL_hid_write(request->device->dev, request->data, request->size);
             }
-            SDL_UnlockMutex(request->device->dev_lock);
             if (request->callback) {
                 request->callback(request->userdata);
             }

+ 0 - 10
src/joystick/hidapi/SDL_hidapi_switch.c

@@ -2726,17 +2726,7 @@ static void HandleFullControllerState(SDL_Joystick *joystick, SDL_DriverSwitch_C
             Uint64 now = SDL_GetTicks();
 
             if (now >= (ctx->m_ulLastIMUReset + IMU_RESET_DELAY_MS)) {
-                SDL_HIDAPI_Device *device = ctx->device;
-
-                if (device->updating) {
-                    SDL_UnlockMutex(device->dev_lock);
-                }
-
                 SetIMUEnabled(ctx, true);
-
-                if (device->updating) {
-                    SDL_LockMutex(device->dev_lock);
-                }
                 ctx->m_ulLastIMUReset = now;
             }
 

+ 10 - 34
src/joystick/hidapi/SDL_hidapijoystick.c

@@ -72,7 +72,7 @@ static SDL_HIDAPI_DeviceDriver *SDL_HIDAPI_drivers[] = {
 #endif
 #ifdef SDL_JOYSTICK_HIDAPI_STEAMDECK
     &SDL_HIDAPI_DriverSteamTriton,
-#endif 
+#endif
 #ifdef SDL_JOYSTICK_HIDAPI_SWITCH
     &SDL_HIDAPI_DriverNintendoClassic,
     &SDL_HIDAPI_DriverJoyCons,
@@ -439,19 +439,15 @@ static void HIDAPI_CleanupDeviceDriver(SDL_HIDAPI_Device *device)
     device->driver->FreeDevice(device);
     device->driver = NULL;
 
-    SDL_LockMutex(device->dev_lock);
-    {
-        if (device->dev) {
-            SDL_hid_close(device->dev);
-            device->dev = NULL;
-        }
+    if (device->dev) {
+        SDL_hid_close(device->dev);
+        device->dev = NULL;
+    }
 
-        if (device->context) {
-            SDL_free(device->context);
-            device->context = NULL;
-        }
+    if (device->context) {
+        SDL_free(device->context);
+        device->context = NULL;
     }
-    SDL_UnlockMutex(device->dev_lock);
 }
 
 static void HIDAPI_SetupDeviceDriver(SDL_HIDAPI_Device *device, bool *removed) SDL_NO_THREAD_SAFETY_ANALYSIS // We unlock the joystick lock to be able to open the HID device on Android
@@ -916,7 +912,6 @@ static SDL_HIDAPI_Device *HIDAPI_AddDevice(const struct SDL_hid_device_info *inf
     device->usage_page = info->usage_page;
     device->usage = info->usage;
     device->is_bluetooth = (info->bus_type == SDL_HID_API_BUS_BLUETOOTH);
-    device->dev_lock = SDL_CreateMutex();
 
     // Need the device name before getting the driver to know whether to ignore this device
     {
@@ -1013,7 +1008,6 @@ static void HIDAPI_DelDevice(SDL_HIDAPI_Device *device)
             }
 
             SDL_SetObjectValid(device, SDL_OBJECT_TYPE_HIDAPI_JOYSTICK, false);
-            SDL_DestroyMutex(device->dev_lock);
             SDL_free(device->manufacturer_string);
             SDL_free(device->product_string);
             SDL_free(device->serial);
@@ -1434,12 +1428,7 @@ void HIDAPI_UpdateDevices(void)
                 continue;
             }
             if (device->driver) {
-                if (SDL_TryLockMutex(device->dev_lock)) {
-                    device->updating = true;
-                    device->driver->UpdateDevice(device);
-                    device->updating = false;
-                    SDL_UnlockMutex(device->dev_lock);
-                }
+                device->driver->UpdateDevice(device);
             }
         }
         HIDAPI_FinishUpdatingDevices();
@@ -1552,11 +1541,7 @@ static bool HIDAPI_JoystickOpen(SDL_Joystick *joystick, int device_index)
     hwdata->device = device;
 
     // Process any pending reports before opening the device
-    SDL_LockMutex(device->dev_lock);
-    device->updating = true;
     device->driver->UpdateDevice(device);
-    device->updating = false;
-    SDL_UnlockMutex(device->dev_lock);
 
     // UpdateDevice() may have called HIDAPI_JoystickDisconnected() if the device went away
     if (device->num_joysticks == 0) {
@@ -1682,22 +1667,13 @@ static void HIDAPI_JoystickClose(SDL_Joystick *joystick) SDL_NO_THREAD_SAFETY_AN
 
     if (joystick->hwdata) {
         SDL_HIDAPI_Device *device = joystick->hwdata->device;
-        int i;
 
         // Wait up to 30 ms for pending rumble to complete
-        if (device->updating) {
-            // Unlock the device so rumble can complete
-            SDL_UnlockMutex(device->dev_lock);
-        }
-        for (i = 0; i < 3; ++i) {
+        for (int i = 0; i < 3; ++i) {
             if (SDL_GetAtomicInt(&device->rumble_pending) > 0) {
                 SDL_Delay(10);
             }
         }
-        if (device->updating) {
-            // Relock the device
-            SDL_LockMutex(device->dev_lock);
-        }
 
         device->driver->CloseJoystick(device, joystick);
 

+ 0 - 4
src/joystick/hidapi/SDL_hidapijoystick_c.h

@@ -100,7 +100,6 @@ typedef struct SDL_HIDAPI_Device
 
     struct SDL_HIDAPI_DeviceDriver *driver;
     void *context;
-    SDL_Mutex *dev_lock;
     SDL_hid_device *dev;
     SDL_AtomicInt rumble_pending;
     int num_joysticks;
@@ -109,9 +108,6 @@ typedef struct SDL_HIDAPI_Device
     // Used during scanning for device changes
     bool seen;
 
-    // Used to flag that the device is being updated
-    bool updating;
-
     // Used to flag devices that failed open
     // This can happen on Windows with Bluetooth devices that have turned off
     bool broken;