diff options
author | Jeremy Huddleston <jeremyhu@freedesktop.org> | 2008-06-04 12:01:19 -0700 |
---|---|---|
committer | Jeremy Huddleston <jeremyhu@freedesktop.org> | 2008-06-04 12:24:12 -0700 |
commit | ee86b751192b690973ee2a1446a406bc721ce8eb (patch) | |
tree | 17a837e647cd84962f0e3d40c666d017e7b952ed /hw/xquartz/darwinEvents.c | |
parent | 38da26cd36957a45b2a47ef124282f7d863a9fd3 (diff) |
XQuartz: use a condition variable to signal when darwinEvents is ready rather than polling
(cherry picked from commit ff1c443cadf11d12a7d939e51194f6105153870e)
Diffstat (limited to 'hw/xquartz/darwinEvents.c')
-rw-r--r-- | hw/xquartz/darwinEvents.c | 53 |
1 files changed, 34 insertions, 19 deletions
diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c index 0ecb064c4..1e79cd3bc 100644 --- a/hw/xquartz/darwinEvents.c +++ b/hw/xquartz/darwinEvents.c @@ -80,21 +80,36 @@ void QuartzModeEQInit(void); static int old_flags = 0; // last known modifier state static xEvent *darwinEvents = NULL; -static pthread_mutex_t darwinEvents_mutex = PTHREAD_MUTEX_INITIALIZER; + +static pthread_mutex_t mieq_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t mieq_ready_cond = PTHREAD_COND_INITIALIZER; static inline void darwinEvents_lock(void) { int err; - if((err = pthread_mutex_lock(&darwinEvents_mutex))) { - ErrorF("%s:%s:%d: Failed to lock darwinEvents_mutex: %d\n", + if((err = pthread_mutex_lock(&mieq_lock))) { + ErrorF("%s:%s:%d: Failed to lock mieq_lock: %d\n", __FILE__, __FUNCTION__, __LINE__, err); spewCallStack(); } + if(darwinEvents == NULL) { + pthread_cond_wait(&mieq_ready_cond, &mieq_lock); + + /* We want to give xinit time to finish running xinitrc before we accept + * the launchd socket connection. + * + * Yes, we lock then immediately unlock because the lock does a cond_wait + * when darwinEvents == NULL + * + * TODO: Cleanup this race more elegantly. + */ + sleep(2); + } } static inline void darwinEvents_unlock(void) { int err; - if((err = pthread_mutex_unlock(&darwinEvents_mutex))) { - ErrorF("%s:%s:%d: Failed to unlock darwinEvents_mutex: %d\n", + if((err = pthread_mutex_unlock(&mieq_lock))) { + ErrorF("%s:%s:%d: Failed to unlock mieq_lock: %d\n", __FILE__, __FUNCTION__, __LINE__, err); spewCallStack(); } @@ -333,11 +348,17 @@ Bool DarwinEQInit(void) { QuartzModeEQInit(); - if (!darwinEvents) + if (!darwinEvents) { darwinEvents = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum()); - if (!darwinEvents) - FatalError("Couldn't allocate event buffer\n"); - + + if (!darwinEvents) + FatalError("Couldn't allocate event buffer\n"); + + darwinEvents_lock(); + pthread_cond_broadcast(&mieq_ready_cond); + darwinEvents_unlock(); + } + return TRUE; } @@ -453,7 +474,6 @@ void DarwinSendPointerEvents(int ev_type, int ev_button, int pointer_x, int poin POINTER_ABSOLUTE, 0, dev==darwinTablet?5:2, valuators); for(i=0; i<num_events; i++) mieqEnqueue (dev, &darwinEvents[i]); DarwinPokeEQ(); - } darwinEvents_unlock(); } @@ -578,13 +598,8 @@ void DarwinSendDDXEvent(int type, int argc, ...) { va_end (args); } - /* If we're called from something other than the X server thread, we need - * to wait for the X server to setup darwinEvents. - */ - while(darwinEvents == NULL) { - usleep(250000); - } - - mieqEnqueue(darwinPointer, &xe); - DarwinPokeEQ(); + darwinEvents_lock(); { + mieqEnqueue(darwinPointer, &xe); + DarwinPokeEQ(); + } darwinEvents_unlock(); } |