From 58af89008562c33ba221f0ee9451ca1ae71445d9 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 27 Jan 2011 22:44:08 -0800 Subject: [PATCH] Removed completely non-portable event thread hack. Next I'll be working on generalizing the event sources and making the event queue lock-free. :) --- include/SDL.h | 1 - include/SDL_video.h | 5 +- src/SDL.c | 2 +- src/events/SDL_events.c | 185 +++-------------------- src/events/SDL_events_c.h | 7 +- src/events/SDL_keyboard.c | 2 +- src/joystick/SDL_joystick.c | 16 -- src/video/SDL_video.c | 26 ++-- src/video/directfb/SDL_DirectFB_events.c | 1 - src/video/dummy/SDL_nullevents.c | 1 - src/video/nds/SDL_ndsevents.c | 1 - src/video/pandora/SDL_pandora_events.c | 1 - src/video/uikit/SDL_uikitevents.m | 1 - test/common.c | 2 +- test/testshape.c | 2 +- test/threadwin.c | 16 +- 16 files changed, 43 insertions(+), 226 deletions(-) diff --git a/include/SDL.h b/include/SDL.h index 0f4eb35b0..88af953cc 100644 --- a/include/SDL.h +++ b/include/SDL.h @@ -116,7 +116,6 @@ extern "C" { #define SDL_INIT_JOYSTICK 0x00000200 #define SDL_INIT_HAPTIC 0x00001000 #define SDL_INIT_NOPARACHUTE 0x00100000 /**< Don't catch fatal signals */ -#define SDL_INIT_EVENTTHREAD 0x01000000 /**< Not supported on all OS's */ #define SDL_INIT_EVERYTHING 0x0000FFFF /*@}*/ diff --git a/include/SDL_video.h b/include/SDL_video.h index 12227fc36..a992a4cac 100644 --- a/include/SDL_video.h +++ b/include/SDL_video.h @@ -278,8 +278,6 @@ extern DECLSPEC const char *SDLCALL SDL_GetVideoDriver(int index); * \param driver_name Initialize a specific driver by name, or NULL for the * default video driver. * - * \param flags FIXME: Still needed? - * * \return 0 on success, -1 on error * * This function initializes the video subsystem; setting up a connection @@ -288,8 +286,7 @@ extern DECLSPEC const char *SDLCALL SDL_GetVideoDriver(int index); * * \sa SDL_VideoQuit() */ -extern DECLSPEC int SDLCALL SDL_VideoInit(const char *driver_name, - Uint32 flags); +extern DECLSPEC int SDLCALL SDL_VideoInit(const char *driver_name); /** * \brief Shuts down the video subsystem. diff --git a/src/SDL.c b/src/SDL.c index cfd73f792..53a1b8a1d 100644 --- a/src/SDL.c +++ b/src/SDL.c @@ -59,7 +59,7 @@ SDL_InitSubSystem(Uint32 flags) #if !SDL_VIDEO_DISABLED /* Initialize the video/event subsystem */ if ((flags & SDL_INIT_VIDEO) && !(SDL_initialized & SDL_INIT_VIDEO)) { - if (SDL_VideoInit(NULL, (flags & SDL_INIT_EVENTTHREAD)) < 0) { + if (SDL_VideoInit(NULL) < 0) { return (-1); } SDL_initialized |= SDL_INIT_VIDEO; diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c index b3c2ad818..af4af7588 100644 --- a/src/events/SDL_events.c +++ b/src/events/SDL_events.c @@ -27,12 +27,12 @@ #include "SDL_events.h" #include "SDL_syswm.h" #include "SDL_thread.h" -#include "SDL_sysevents.h" #include "SDL_events_c.h" #include "../timer/SDL_timer_c.h" #if !SDL_JOYSTICK_DISABLED #include "../joystick/SDL_joystick_c.h" #endif +#include "../video/SDL_sysvideo.h" /* Public data -- the event filter */ SDL_EventFilter SDL_EventOK = NULL; @@ -58,36 +58,6 @@ static struct struct SDL_SysWMmsg wmmsg[MAXEVENTS]; } SDL_EventQ; -/* Private data -- event locking structure */ -static struct -{ - SDL_mutex *lock; - int safe; -} SDL_EventLock; - -/* Thread functions */ -static SDL_Thread *SDL_EventThread = NULL; /* Thread handle */ -static SDL_threadID event_thread; /* The event thread id */ - -void -SDL_Lock_EventThread(void) -{ - if (SDL_EventThread && (SDL_ThreadID() != event_thread)) { - /* Grab lock and spin until we're sure event thread stopped */ - SDL_mutexP(SDL_EventLock.lock); - while (!SDL_EventLock.safe) { - SDL_Delay(1); - } - } -} - -void -SDL_Unlock_EventThread(void) -{ - if (SDL_EventThread && (SDL_ThreadID() != event_thread)) { - SDL_mutexV(SDL_EventLock.lock); - } -} static __inline__ SDL_bool SDL_ShouldPollJoystick() @@ -102,106 +72,6 @@ SDL_ShouldPollJoystick() return SDL_FALSE; } -static int SDLCALL -SDL_GobbleEvents(void *unused) -{ - event_thread = SDL_ThreadID(); - - while (SDL_EventQ.active) { - SDL_VideoDevice *_this = SDL_GetVideoDevice(); - - /* Get events from the video subsystem */ - if (_this) { - _this->PumpEvents(_this); - } -#if !SDL_JOYSTICK_DISABLED - /* Check for joystick state change */ - if (SDL_ShouldPollJoystick()) { - SDL_JoystickUpdate(); - } -#endif - - /* Give up the CPU for the rest of our timeslice */ - SDL_EventLock.safe = 1; - SDL_Delay(1); - - /* Check for event locking. - On the P of the lock mutex, if the lock is held, this thread - will wait until the lock is released before continuing. The - safe flag will be set, meaning that the other thread can go - about it's business. The safe flag is reset before the V, - so as soon as the mutex is free, other threads can see that - it's not safe to interfere with the event thread. - */ - SDL_mutexP(SDL_EventLock.lock); - SDL_EventLock.safe = 0; - SDL_mutexV(SDL_EventLock.lock); - } - event_thread = 0; - return (0); -} - -static int -SDL_StartEventThread(Uint32 flags) -{ - /* Reset everything to zero */ - SDL_EventThread = NULL; - SDL_memset(&SDL_EventLock, 0, sizeof(SDL_EventLock)); - - /* Create the lock and set ourselves active */ -#if !SDL_THREADS_DISABLED - SDL_EventQ.lock = SDL_CreateMutex(); - if (SDL_EventQ.lock == NULL) { - return (-1); - } -#endif /* !SDL_THREADS_DISABLED */ - SDL_EventQ.active = 1; - - if ((flags & SDL_INIT_EVENTTHREAD) == SDL_INIT_EVENTTHREAD) { - SDL_EventLock.lock = SDL_CreateMutex(); - if (SDL_EventLock.lock == NULL) { - return (-1); - } - SDL_EventLock.safe = 0; - -#if (defined(__WIN32__) && !defined(_WIN32_WCE)) && !defined(HAVE_LIBC) -#undef SDL_CreateThread - SDL_EventThread = - SDL_CreateThread(SDL_GobbleEvents, NULL, NULL, NULL); -#else - SDL_EventThread = SDL_CreateThread(SDL_GobbleEvents, NULL); -#endif - if (SDL_EventThread == NULL) { - return (-1); - } - } else { - event_thread = 0; - } - return (0); -} - -static void -SDL_StopEventThread(void) -{ - SDL_EventQ.active = 0; - if (SDL_EventThread) { - SDL_WaitThread(SDL_EventThread, NULL); - SDL_EventThread = NULL; - SDL_DestroyMutex(SDL_EventLock.lock); - SDL_EventLock.lock = NULL; - } - if (SDL_EventQ.lock) { - SDL_DestroyMutex(SDL_EventQ.lock); - SDL_EventQ.lock = NULL; - } -} - -SDL_threadID -SDL_EventThreadID(void) -{ - return (event_thread); -} - /* Public functions */ void @@ -209,13 +79,10 @@ SDL_StopEventLoop(void) { int i; - /* Halt the event thread, if running */ - SDL_StopEventThread(); - - /* Shutdown event handlers */ - SDL_KeyboardQuit(); - SDL_MouseQuit(); - SDL_QuitQuit(); + if (SDL_EventQ.lock) { + SDL_DestroyMutex(SDL_EventQ.lock); + SDL_EventQ.lock = NULL; + } /* Clean out EventQ */ SDL_EventQ.head = 0; @@ -233,12 +100,11 @@ SDL_StopEventLoop(void) /* This function (and associated calls) may be called more than once */ int -SDL_StartEventLoop(Uint32 flags) +SDL_StartEventLoop(void) { int retcode; /* Clean out the event queue */ - SDL_EventThread = NULL; SDL_EventQ.lock = NULL; SDL_StopEventLoop(); @@ -246,22 +112,15 @@ SDL_StartEventLoop(Uint32 flags) SDL_EventOK = NULL; SDL_EventState(SDL_SYSWMEVENT, SDL_DISABLE); - /* Initialize event handlers */ - retcode = 0; - retcode += SDL_KeyboardInit(); - retcode += SDL_MouseInit(); - retcode += SDL_TouchInit(); - retcode += SDL_QuitInit(); - if (retcode < 0) { - /* We don't expect them to fail, but... */ + /* Create the lock and set ourselves active */ +#if !SDL_THREADS_DISABLED + SDL_EventQ.lock = SDL_CreateMutex(); + if (SDL_EventQ.lock == NULL) { return (-1); } +#endif /* !SDL_THREADS_DISABLED */ + SDL_EventQ.active = 1; - /* Create the lock and event thread */ - if (SDL_StartEventThread(flags) < 0) { - SDL_StopEventLoop(); - return (-1); - } return (0); } @@ -420,20 +279,18 @@ SDL_FlushEvents(Uint32 minType, Uint32 maxType) void SDL_PumpEvents(void) { - if (!SDL_EventThread) { - SDL_VideoDevice *_this = SDL_GetVideoDevice(); + SDL_VideoDevice *_this = SDL_GetVideoDevice(); - /* Get events from the video subsystem */ - if (_this) { - _this->PumpEvents(_this); - } + /* Get events from the video subsystem */ + if (_this) { + _this->PumpEvents(_this); + } #if !SDL_JOYSTICK_DISABLED - /* Check for joystick state change */ - if (SDL_ShouldPollJoystick()) { - SDL_JoystickUpdate(); - } -#endif + /* Check for joystick state change */ + if (SDL_ShouldPollJoystick()) { + SDL_JoystickUpdate(); } +#endif } /* Public functions */ diff --git a/src/events/SDL_events_c.h b/src/events/SDL_events_c.h index ccf29b3da..569e9daea 100644 --- a/src/events/SDL_events_c.h +++ b/src/events/SDL_events_c.h @@ -29,15 +29,12 @@ #include "SDL_touch_c.h" #include "SDL_windowevents_c.h" #include "SDL_gesture_c.h" + /* Start and stop the event processing loop */ -extern int SDL_StartEventLoop(Uint32 flags); +extern int SDL_StartEventLoop(void); extern void SDL_StopEventLoop(void); extern void SDL_QuitInterrupt(void); -extern void SDL_Lock_EventThread(void); -extern void SDL_Unlock_EventThread(void); -extern SDL_threadID SDL_EventThreadID(void); - extern int SDL_SendSysWMEvent(SDL_SysWMmsg * message); extern int SDL_QuitInit(void); diff --git a/src/events/SDL_keyboard.c b/src/events/SDL_keyboard.c index 49948d77c..307dc5386 100644 --- a/src/events/SDL_keyboard.c +++ b/src/events/SDL_keyboard.c @@ -26,7 +26,7 @@ #include "SDL_timer.h" #include "SDL_events.h" #include "SDL_events_c.h" -#include "SDL_sysevents.h" +#include "../video/SDL_sysvideo.h" /* Global keyboard information */ diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index 6a99c4bf9..1ed0d41f3 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -30,12 +30,6 @@ #include "../events/SDL_events_c.h" #endif -/* This is used for Quake III Arena */ -#if SDL_EVENTS_DISABLED -#define SDL_Lock_EventThread() -#define SDL_Unlock_EventThread() -#endif - Uint8 SDL_numjoysticks = 0; SDL_Joystick **SDL_joysticks = NULL; static SDL_Joystick *default_joystick = NULL; @@ -165,11 +159,9 @@ SDL_JoystickOpen(int device_index) /* Add joystick to list */ ++joystick->ref_count; - SDL_Lock_EventThread(); for (i = 0; SDL_joysticks[i]; ++i) /* Skip to next joystick */ ; SDL_joysticks[i] = joystick; - SDL_Unlock_EventThread(); return (joystick); } @@ -379,9 +371,6 @@ SDL_JoystickClose(SDL_Joystick * joystick) return; } - /* Lock the event queue - prevent joystick polling */ - SDL_Lock_EventThread(); - if (joystick == default_joystick) { default_joystick = NULL; } @@ -396,9 +385,6 @@ SDL_JoystickClose(SDL_Joystick * joystick) } } - /* Let the event thread keep running */ - SDL_Unlock_EventThread(); - /* Free the data associated with this joystick */ if (joystick->axes) { SDL_free(joystick->axes); @@ -419,9 +405,7 @@ void SDL_JoystickQuit(void) { /* Stop the event polling */ - SDL_Lock_EventThread(); SDL_numjoysticks = 0; - SDL_Unlock_EventThread(); /* Quit the joystick setup */ SDL_SYS_JoystickQuit(); diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 9d1f85b23..0e4ec105b 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -31,7 +31,6 @@ #include "SDL_renderer_gl.h" #include "SDL_renderer_gles.h" #include "SDL_renderer_sw.h" -#include "../events/SDL_sysevents.h" #include "../events/SDL_events_c.h" #if SDL_VIDEO_DRIVER_WINDOWS @@ -172,7 +171,7 @@ SDL_GetVideoDriver(int index) * Initialize the video and event subsystems -- determine native pixel format */ int -SDL_VideoInit(const char *driver_name, Uint32 flags) +SDL_VideoInit(const char *driver_name) { SDL_VideoDevice *video; int index; @@ -183,18 +182,12 @@ SDL_VideoInit(const char *driver_name, Uint32 flags) SDL_VideoQuit(); } - /* Toggle the event thread flags, based on OS requirements */ -#if defined(MUST_THREAD_EVENTS) - flags |= SDL_INIT_EVENTTHREAD; -#elif defined(CANT_THREAD_EVENTS) - if ((flags & SDL_INIT_EVENTTHREAD) == SDL_INIT_EVENTTHREAD) { - SDL_SetError("OS doesn't support threaded events"); - return -1; - } -#endif - /* Start the event loop */ - if (SDL_StartEventLoop(flags) < 0) { + if (SDL_StartEventLoop() < 0 || + SDL_KeyboardInit() < 0 || + SDL_MouseInit() < 0 || + SDL_TouchInit() < 0 || + SDL_QuitInit() < 0) { return -1; } @@ -887,7 +880,7 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags) if (!_this) { /* Initialize the video system if needed */ - if (SDL_VideoInit(NULL, 0) < 0) { + if (SDL_VideoInit(NULL) < 0) { return NULL; } } @@ -2807,8 +2800,13 @@ SDL_VideoQuit(void) if (!_this) { return; } + /* Halt event processing before doing anything else */ + SDL_QuitQuit(); + SDL_MouseQuit(); + SDL_KeyboardQuit(); SDL_StopEventLoop(); + SDL_EnableScreenSaver(); /* Clean up the system video */ diff --git a/src/video/directfb/SDL_DirectFB_events.c b/src/video/directfb/SDL_DirectFB_events.c index 97a821515..e994249bc 100644 --- a/src/video/directfb/SDL_DirectFB_events.c +++ b/src/video/directfb/SDL_DirectFB_events.c @@ -26,7 +26,6 @@ #include #include "../SDL_sysvideo.h" -#include "../../events/SDL_sysevents.h" #include "../../events/SDL_events_c.h" #include "../../events/SDL_keyboard_c.h" #include "../../events/scancodes_linux.h" diff --git a/src/video/dummy/SDL_nullevents.c b/src/video/dummy/SDL_nullevents.c index 195b8fc69..e164f8439 100644 --- a/src/video/dummy/SDL_nullevents.c +++ b/src/video/dummy/SDL_nullevents.c @@ -24,7 +24,6 @@ /* Being a null driver, there's no event stream. We just define stubs for most of the API. */ -#include "../../events/SDL_sysevents.h" #include "../../events/SDL_events_c.h" #include "SDL_nullvideo.h" diff --git a/src/video/nds/SDL_ndsevents.c b/src/video/nds/SDL_ndsevents.c index 94db798c8..5dc06d9ae 100644 --- a/src/video/nds/SDL_ndsevents.c +++ b/src/video/nds/SDL_ndsevents.c @@ -28,7 +28,6 @@ #include #include -#include "../../events/SDL_sysevents.h" #include "../../events/SDL_events_c.h" #include "SDL_ndsvideo.h" diff --git a/src/video/pandora/SDL_pandora_events.c b/src/video/pandora/SDL_pandora_events.c index e44899776..eb3aa8566 100644 --- a/src/video/pandora/SDL_pandora_events.c +++ b/src/video/pandora/SDL_pandora_events.c @@ -24,7 +24,6 @@ /* Being a null driver, there's no event stream. We just define stubs for most of the API. */ -#include "../../events/SDL_sysevents.h" #include "../../events/SDL_events_c.h" void diff --git a/src/video/uikit/SDL_uikitevents.m b/src/video/uikit/SDL_uikitevents.m index 12b1e281b..e59a043a7 100644 --- a/src/video/uikit/SDL_uikitevents.m +++ b/src/video/uikit/SDL_uikitevents.m @@ -21,7 +21,6 @@ */ #include "SDL_config.h" -#include "../../events/SDL_sysevents.h" #include "../../events/SDL_events_c.h" #include "SDL_uikitvideo.h" diff --git a/test/common.c b/test/common.c index 7b48a644f..968efb0b5 100644 --- a/test/common.c +++ b/test/common.c @@ -616,7 +616,7 @@ CommonInit(CommonState * state) fprintf(stderr, "\n"); } } - if (SDL_VideoInit(state->videodriver, 0) < 0) { + if (SDL_VideoInit(state->videodriver) < 0) { fprintf(stderr, "Couldn't initialize video driver: %s\n", SDL_GetError()); return SDL_FALSE; diff --git a/test/testshape.c b/test/testshape.c index ba14dae99..495944aad 100644 --- a/test/testshape.c +++ b/test/testshape.c @@ -60,7 +60,7 @@ int main(int argc,char** argv) { exit(-1); } - if(SDL_VideoInit(NULL,0) == -1) { + if(SDL_VideoInit(NULL) == -1) { printf("Could not initialize SDL video.\n"); exit(-2); } diff --git a/test/threadwin.c b/test/threadwin.c index dfd1c3c9c..08c149f92 100644 --- a/test/threadwin.c +++ b/test/threadwin.c @@ -241,16 +241,7 @@ main(int argc, char *argv[]) video_flags = SDL_SWSURFACE; parsed = 1; while (parsed) { - /* If the threaded option is enabled, and the SDL library hasn't - been compiled with threaded events enabled, then the mouse and - keyboard won't respond. - */ - if ((argc >= 2) && (strcmp(argv[1], "-threaded") == 0)) { - init_flags |= SDL_INIT_EVENTTHREAD; - argc -= 1; - argv += 1; - printf("Running with threaded events\n"); - } else if ((argc >= 2) && (strcmp(argv[1], "-fullscreen") == 0)) { + if ((argc >= 2) && (strcmp(argv[1], "-fullscreen") == 0)) { video_flags |= SDL_FULLSCREEN; argc -= 1; argv += 1; @@ -320,9 +311,8 @@ main(int argc, char *argv[]) /* Loop, waiting for QUIT */ while (!done) { - if (!(init_flags & SDL_INIT_EVENTTHREAD)) { - SDL_PumpEvents(); /* Needed when event thread is off */ - } + SDL_PumpEvents(); + if (SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, SDL_QUIT, SDL_QUIT)) { done = 1; }