Make sure we don't read and write to HIDAPI at the same time, it's not thread-safe on Windows
authorSam Lantinga <slouken@libsdl.org>
Tue, 02 Oct 2018 20:51:33 -0700
changeset 122778b916fc4f50f
parent 12276 9add34050395
child 12284 fe9bafcd47ba
Make sure we don't read and write to HIDAPI at the same time, it's not thread-safe on Windows
src/joystick/hidapi/SDL_hidapijoystick.c
     1.1 --- a/src/joystick/hidapi/SDL_hidapijoystick.c	Tue Oct 02 13:17:31 2018 -0700
     1.2 +++ b/src/joystick/hidapi/SDL_hidapijoystick.c	Tue Oct 02 20:51:33 2018 -0700
     1.3 @@ -25,6 +25,7 @@
     1.4  #include "SDL_endian.h"
     1.5  #include "SDL_hints.h"
     1.6  #include "SDL_log.h"
     1.7 +#include "SDL_mutex.h"
     1.8  #include "SDL_thread.h"
     1.9  #include "SDL_timer.h"
    1.10  #include "SDL_joystick.h"
    1.11 @@ -54,6 +55,7 @@
    1.12      SDL_HIDAPI_DeviceDriver *driver;
    1.13      void *context;
    1.14  
    1.15 +    SDL_mutex *mutex;
    1.16      hid_device *dev;
    1.17  };
    1.18  
    1.19 @@ -959,6 +961,7 @@
    1.20          SDL_free(hwdata);
    1.21          return SDL_SetError("Couldn't open HID device %s", device->path);
    1.22      }
    1.23 +    hwdata->mutex = SDL_CreateMutex();
    1.24  
    1.25      if (!device->driver->Init(joystick, hwdata->dev, device->vendor_id, device->product_id, &hwdata->context)) {
    1.26          hid_close(hwdata->dev);
    1.27 @@ -975,7 +978,12 @@
    1.28  {
    1.29      struct joystick_hwdata *hwdata = joystick->hwdata;
    1.30      SDL_HIDAPI_DeviceDriver *driver = hwdata->driver;
    1.31 -    return driver->Rumble(joystick, hwdata->dev, hwdata->context, low_frequency_rumble, high_frequency_rumble, duration_ms);
    1.32 +    int result;
    1.33 +
    1.34 +    SDL_LockMutex(hwdata->mutex);
    1.35 +    result = driver->Rumble(joystick, hwdata->dev, hwdata->context, low_frequency_rumble, high_frequency_rumble, duration_ms);
    1.36 +    SDL_UnlockMutex(hwdata->mutex);
    1.37 +    return result;
    1.38  }
    1.39  
    1.40  static void
    1.41 @@ -983,7 +991,13 @@
    1.42  {
    1.43      struct joystick_hwdata *hwdata = joystick->hwdata;
    1.44      SDL_HIDAPI_DeviceDriver *driver = hwdata->driver;
    1.45 -    if (!driver->Update(joystick, hwdata->dev, hwdata->context)) {
    1.46 +    SDL_bool succeeded;
    1.47 +
    1.48 +    SDL_LockMutex(hwdata->mutex);
    1.49 +    succeeded = driver->Update(joystick, hwdata->dev, hwdata->context);
    1.50 +    SDL_UnlockMutex(hwdata->mutex);
    1.51 +    
    1.52 +    if (!succeeded) {
    1.53          SDL_HIDAPI_Device *device;
    1.54          for (device = SDL_HIDAPI_devices; device; device = device->next) {
    1.55              if (device->instance_id == joystick->instance_id) {
    1.56 @@ -1002,6 +1016,7 @@
    1.57      driver->Quit(joystick, hwdata->dev, hwdata->context);
    1.58  
    1.59      hid_close(hwdata->dev);
    1.60 +    SDL_DestroyMutex(hwdata->mutex);
    1.61      SDL_free(hwdata);
    1.62      joystick->hwdata = NULL;
    1.63  }