diff --git a/src/joystick/SDL_gamepad.c b/src/joystick/SDL_gamepad.c index d7fd03d9a3..004c647e6e 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 c69d297b78..4b6ff4cf6d 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 c3d68e1f50..823a2cbc04 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) {