Skip to content

Commit

Permalink
Fixed crash if there are multiple joysticks closed during the joystic…
Browse files Browse the repository at this point in the history
…k update loop
  • Loading branch information
slouken committed Dec 14, 2016
1 parent f50a040 commit b4ea63e
Showing 1 changed file with 12 additions and 15 deletions.
27 changes: 12 additions & 15 deletions src/joystick/SDL_joystick.c
Expand Up @@ -34,7 +34,7 @@

static SDL_bool SDL_joystick_allows_background_events = SDL_FALSE;
static SDL_Joystick *SDL_joysticks = NULL;
static SDL_Joystick *SDL_updating_joystick = NULL;
static SDL_bool SDL_updating_joystick = SDL_FALSE;
static SDL_mutex *SDL_joystick_lock = NULL; /* This needs to support recursive locks */

void
Expand Down Expand Up @@ -458,7 +458,7 @@ SDL_JoystickClose(SDL_Joystick * joystick)
return;
}

if (joystick == SDL_updating_joystick) {
if (SDL_updating_joystick) {
SDL_UnlockJoystickList();
return;
}
Expand Down Expand Up @@ -784,7 +784,7 @@ SDL_PrivateJoystickButton(SDL_Joystick * joystick, Uint8 button, Uint8 state)
void
SDL_JoystickUpdate(void)
{
SDL_Joystick *joystick, *joysticknext;
SDL_Joystick *joystick;

SDL_LockJoystickList();

Expand All @@ -794,17 +794,12 @@ SDL_JoystickUpdate(void)
return;
}

for (joystick = SDL_joysticks; joystick; joystick = joysticknext) {
/* save off the next pointer, the Update call may cause a joystick removed event
* and cause our joystick pointer to be freed
*/
joysticknext = joystick->next;

SDL_updating_joystick = joystick;
SDL_updating_joystick = SDL_TRUE;

/* Make sure the list is unlocked while dispatching events to prevent application deadlocks */
SDL_UnlockJoystickList();
/* Make sure the list is unlocked while dispatching events to prevent application deadlocks */
SDL_UnlockJoystickList();

for (joystick = SDL_joysticks; joystick; joystick = joystick->next) {
SDL_SYS_JoystickUpdate(joystick);

if (joystick->force_recentering) {
Expand All @@ -825,12 +820,14 @@ SDL_JoystickUpdate(void)

joystick->force_recentering = SDL_FALSE;
}
}

SDL_LockJoystickList();
SDL_LockJoystickList();

SDL_updating_joystick = NULL;
SDL_updating_joystick = SDL_FALSE;

/* If the joystick was closed while updating, free it here */
/* If any joysticks were closed while updating, free them here */
for (joystick = SDL_joysticks; joystick; joystick = joystick->next) {
if (joystick->ref_count <= 0) {
SDL_JoystickClose(joystick);
}
Expand Down

0 comments on commit b4ea63e

Please sign in to comment.