android: fixed a possible joystick-related deadlock on application termination

This commit is contained in:
Sam Lantinga
2026-05-21 12:20:03 -07:00
parent fe1918a47f
commit 6b4ae68460

View File

@@ -178,6 +178,26 @@ static void Android_OnDestroy(void)
static void Android_HandleLifecycleEvent(SDL_AndroidLifecycleEvent event)
{
// Make sure we're holding the joystick lock before dispatching life cycle events
// This prevents deadlocks of this form:
// 1. SDL locks the event watch list to dispatch the lifecycle event
// 2. a joystick sensor event arrives, taking the joystick lock
// 3. the lifecycle event dispatch calls into the application event
// watcher, which closes joysticks, trying to take the joystick lock
// 4. SDL delivers the sensor event, trying lock the event watch list
// 5. BOOM, deadlock!
//
// There are a few solutions to this, most of which involve unlocking the
// event watch list while delivering events or unlocking the joystick lock
// while delivering joystick events, both of which reduce performance and
// are extremely risky, so we'll do this, which is the least risky option.
//
// If you end up needing to wait for another thread that handles joystick
// events in your life cycle handling, then you can simply unlock joysticks,
// wait for that thread to complete, and then re-lock joysticks.
SDL_LockJoysticks();
switch (event) {
case SDL_ANDROID_LIFECYCLE_WAKE:
// Nothing to do, just return
@@ -197,6 +217,8 @@ static void Android_HandleLifecycleEvent(SDL_AndroidLifecycleEvent event)
default:
break;
}
SDL_UnlockJoysticks();
}
static Sint64 GetLifecycleEventTimeout(bool paused, Sint64 timeoutNS)