mirror of
https://github.com/Ryujinx/SDL.git
synced 2024-12-23 15:15:39 +00:00
Reduce the chance of destroying the joystick mutex while it's in use
Fixes https://github.com/libsdl-org/SDL/issues/7811 (cherry picked from commit 6390165fd4c193631d6780758a4aeec0d02b90eb)
This commit is contained in:
parent
2afb49ba9a
commit
e4e0a12901
|
@ -114,6 +114,7 @@ static SDL_JoystickDriver *SDL_joystick_drivers[] = {
|
||||||
static
|
static
|
||||||
#endif
|
#endif
|
||||||
SDL_mutex *SDL_joystick_lock = NULL; /* This needs to support recursive locks */
|
SDL_mutex *SDL_joystick_lock = NULL; /* This needs to support recursive locks */
|
||||||
|
static SDL_atomic_t SDL_joystick_lock_pending;
|
||||||
static int SDL_joysticks_locked;
|
static int SDL_joysticks_locked;
|
||||||
static SDL_bool SDL_joysticks_initialized;
|
static SDL_bool SDL_joysticks_initialized;
|
||||||
static SDL_bool SDL_joysticks_quitting = SDL_FALSE;
|
static SDL_bool SDL_joysticks_quitting = SDL_FALSE;
|
||||||
|
@ -143,23 +144,35 @@ SDL_bool SDL_JoysticksQuitting(void)
|
||||||
|
|
||||||
void SDL_LockJoysticks(void)
|
void SDL_LockJoysticks(void)
|
||||||
{
|
{
|
||||||
|
SDL_AtomicIncRef(&SDL_joystick_lock_pending);
|
||||||
SDL_LockMutex(SDL_joystick_lock);
|
SDL_LockMutex(SDL_joystick_lock);
|
||||||
|
SDL_AtomicDecRef(&SDL_joystick_lock_pending);
|
||||||
|
|
||||||
++SDL_joysticks_locked;
|
++SDL_joysticks_locked;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDL_UnlockJoysticks(void)
|
void SDL_UnlockJoysticks(void)
|
||||||
{
|
{
|
||||||
|
SDL_mutex *joystick_lock = SDL_joystick_lock;
|
||||||
|
SDL_bool last_unlock = SDL_FALSE;
|
||||||
|
|
||||||
--SDL_joysticks_locked;
|
--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,
|
/* The last unlock after joysticks are uninitialized will cleanup the mutex,
|
||||||
* allowing applications to lock joysticks while reinitializing the system.
|
* allowing applications to lock joysticks while reinitializing the system.
|
||||||
*/
|
*/
|
||||||
if (SDL_joystick_lock && !SDL_joysticks_locked && !SDL_joysticks_initialized) {
|
if (last_unlock) {
|
||||||
SDL_DestroyMutex(SDL_joystick_lock);
|
SDL_DestroyMutex(joystick_lock);
|
||||||
SDL_joystick_lock = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue