Removed completely non-portable event thread hack.

Next I'll be working on generalizing the event sources and making the event queue lock-free. :)
This commit is contained in:
Sam Lantinga 2011-01-27 22:44:08 -08:00
parent 95dbe47cf3
commit c3daf0f0cd
16 changed files with 44 additions and 227 deletions

View file

@ -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);
}
#if !SDL_JOYSTICK_DISABLED
/* Check for joystick state change */
if (SDL_ShouldPollJoystick()) {
SDL_JoystickUpdate();
}
#endif
/* 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
}
/* Public functions */