|
@@ -109,6 +109,7 @@ static SDL_JoystickDriver *SDL_joystick_drivers[] = {
|
|
|
static
|
|
|
#endif
|
|
|
SDL_Mutex *SDL_joystick_lock = NULL; /* This needs to support recursive locks */
|
|
|
+static SDL_AtomicInt SDL_joystick_lock_pending;
|
|
|
static int SDL_joysticks_locked;
|
|
|
static SDL_bool SDL_joysticks_initialized;
|
|
|
static SDL_bool SDL_joysticks_quitting = SDL_FALSE;
|
|
@@ -138,23 +139,35 @@ SDL_bool SDL_JoysticksQuitting(void)
|
|
|
|
|
|
void SDL_LockJoysticks(void)
|
|
|
{
|
|
|
+ SDL_AtomicIncRef(&SDL_joystick_lock_pending);
|
|
|
SDL_LockMutex(SDL_joystick_lock);
|
|
|
+ SDL_AtomicDecRef(&SDL_joystick_lock_pending);
|
|
|
|
|
|
++SDL_joysticks_locked;
|
|
|
}
|
|
|
|
|
|
void SDL_UnlockJoysticks(void)
|
|
|
{
|
|
|
+ SDL_Mutex *joystick_lock = SDL_joystick_lock;
|
|
|
+ SDL_bool last_unlock = SDL_FALSE;
|
|
|
+
|
|
|
--SDL_joysticks_locked;
|
|
|
|
|
|
- SDL_UnlockMutex(SDL_joystick_lock);
|
|
|
+ if (!SDL_joysticks_initialized) {
|
|
|
+ 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 (SDL_joystick_lock && !SDL_joysticks_locked && !SDL_joysticks_initialized) {
|
|
|
- SDL_DestroyMutex(SDL_joystick_lock);
|
|
|
- SDL_joystick_lock = NULL;
|
|
|
+ if (last_unlock) {
|
|
|
+ SDL_DestroyMutex(joystick_lock);
|
|
|
}
|
|
|
}
|
|
|
|