mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-05-24 22:09:54 +00:00
android: fixed a possible joystick-related deadlock on application termination
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user