From 7232e51a68155b7d84a0181cb242088c2d1d4b6d Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 8 Jun 2015 01:52:43 -0400 Subject: [PATCH] Unix: Don't send quit events during signal handler. Make note to send it, and send next time we SDL_PumpEvents(). Otherwise, we might be trying to use malloc() to push a new event on the queue while a signal is interrupting malloc() elsewhere, usually causing a crash. Fixes Bugzilla #2870. --- src/events/SDL_events.c | 2 ++ src/events/SDL_events_c.h | 2 ++ src/events/SDL_quit.c | 18 +++++++++++++++--- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c index edfc3ed124ddd..4f5bb2d9aff50 100644 --- a/src/events/SDL_events.c +++ b/src/events/SDL_events.c @@ -406,6 +406,8 @@ SDL_PumpEvents(void) SDL_JoystickUpdate(); } #endif + + SDL_SendPendingQuit(); /* in case we had a signal handler fire, etc. */ } /* Public functions */ diff --git a/src/events/SDL_events_c.h b/src/events/SDL_events_c.h index 0289590bb34d8..ebd983d36249d 100644 --- a/src/events/SDL_events_c.h +++ b/src/events/SDL_events_c.h @@ -43,6 +43,8 @@ extern int SDL_QuitInit(void); extern int SDL_SendQuit(void); extern void SDL_QuitQuit(void); +extern void SDL_SendPendingQuit(void); + /* The event filter function */ extern SDL_EventFilter SDL_EventOK; extern void *SDL_EventOKParam; diff --git a/src/events/SDL_quit.c b/src/events/SDL_quit.c index 914b5bf668c7a..d2b215bc478b6 100644 --- a/src/events/SDL_quit.c +++ b/src/events/SDL_quit.c @@ -20,6 +20,7 @@ */ #include "../SDL_internal.h" #include "SDL_hints.h" +#include "SDL_assert.h" /* General quit handling code for SDL */ @@ -30,8 +31,8 @@ #include "SDL_events.h" #include "SDL_events_c.h" - static SDL_bool disable_signals = SDL_FALSE; +static SDL_bool send_quit_pending = SDL_FALSE; #ifdef HAVE_SIGNAL_H static void @@ -40,8 +41,9 @@ SDL_HandleSIG(int sig) /* Reset the signal handler */ signal(sig, SDL_HandleSIG); - /* Signal a quit interrupt */ - SDL_SendQuit(); + /* Send a quit event next time the event loop pumps. */ + /* We can't send it in signal handler; malloc() might be interrupted! */ + send_quit_pending = SDL_TRUE; } #endif /* HAVE_SIGNAL_H */ @@ -136,7 +138,17 @@ SDL_QuitQuit(void) int SDL_SendQuit(void) { + send_quit_pending = SDL_FALSE; return SDL_SendAppEvent(SDL_QUIT); } +void +SDL_SendPendingQuit(void) +{ + if (send_quit_pending) { + SDL_SendQuit(); + SDL_assert(!send_quit_pending); + } +} + /* vi: set ts=4 sw=4 expandtab: */