From ca46c01869768a8661a9d8a71493ed5f0760a8ab Mon Sep 17 00:00:00 2001 From: Jeremy Huddleston Date: Fri, 16 Jan 2009 13:58:20 -0800 Subject: XQuartz: mieq: Wait for the server to finish initializing before letting other threads mieqEnqueue Avoid possible race condition whereby one thread might call mieqEnqueue before InitAndStartDevices finishes (cherry picked from commit 94e417ac87a98cd5c6bf2d7c495d702748398931) --- dix/main.c | 14 ++++++++++++++ mi/mieq.c | 34 +++++++++++++++++++++------------- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/dix/main.c b/dix/main.c index 4a062b7f1..069a17b66 100644 --- a/dix/main.c +++ b/dix/main.c @@ -233,6 +233,12 @@ static int indexForScanlinePad[ 65 ] = { #endif #ifdef XQUARTZ +#include + +BOOL serverInitComplete = FALSE; +pthread_mutex_t serverInitCompleteMutex = PTHREAD_MUTEX_INITIALIZER; +pthread_cond_t serverInitCompleteCond = PTHREAD_COND_INITIALIZER; + int dix_main(int argc, char *argv[], char *envp[]) #else int main(int argc, char *argv[], char *envp[]) @@ -377,6 +383,14 @@ int main(int argc, char *argv[], char *envp[]) } } +#ifdef XQUARTZ + /* Let the other threads know the server is done with its init */ + pthread_mutex_lock(&serverInitCompleteMutex); + serverInitComplete = TRUE; + pthread_cond_broadcast(&serverInitCompleteCond); + pthread_mutex_unlock(&serverInitCompleteMutex); +#endif + NotifyParentProcess(); Dispatch(); diff --git a/mi/mieq.c b/mi/mieq.c index 3ce3c49d3..8a329f5f9 100644 --- a/mi/mieq.c +++ b/mi/mieq.c @@ -36,11 +36,6 @@ in this Software without prior written authorization from The Open Group. #include #endif -#ifdef XQUARTZ -#include -static pthread_mutex_t miEventQueueMutex = PTHREAD_MUTEX_INITIALIZER; -#endif - # include # include # include @@ -86,6 +81,25 @@ typedef struct _EventQueue { static EventQueueRec miEventQueue; static EventListPtr masterEvents; /* for use in mieqProcessInputEvents */ +#ifdef XQUARTZ +#include +static pthread_mutex_t miEventQueueMutex = PTHREAD_MUTEX_INITIALIZER; + +extern BOOL serverInitComplete; +extern pthread_mutex_t serverInitCompleteMutex; +extern pthread_cond_t serverInitCompleteCond; + +static inline void wait_for_server_init(void) { + /* If the server hasn't finished initializing, wait for it... */ + if(!serverInitComplete) { + pthread_mutex_lock(&serverInitCompleteMutex); + while(!serverInitComplete) + pthread_cond_wait(&serverInitCompleteCond, &serverInitCompleteMutex); + pthread_mutex_unlock(&serverInitCompleteMutex); + } +} +#endif + Bool mieqInit(void) { @@ -144,6 +158,7 @@ mieqEnqueue(DeviceIntPtr pDev, xEvent *e) int evlen; #ifdef XQUARTZ + wait_for_server_init(); pthread_mutex_lock(&miEventQueueMutex); #endif @@ -247,14 +262,7 @@ mieqEnqueue(DeviceIntPtr pDev, xEvent *e) evt->event->u.keyButtonPointer.time = miEventQueue.lastEventTime; miEventQueue.lastEventTime = evt->event->u.keyButtonPointer.time; - - /* Avoid possible crash when multithreaded and mieqEnqueue is called before - * InitAndStartDevices finishes. - */ - if(pDev && pDev->spriteInfo && pDev->spriteInfo->sprite) - miEventQueue.events[oldtail].pScreen = EnqueueScreen(pDev); - else - miEventQueue.events[oldtail].pScreen = NULL; + miEventQueue.events[oldtail].pScreen = EnqueueScreen(pDev); miEventQueue.events[oldtail].pDev = pDev; miEventQueue.lastMotion = isMotion; -- cgit v1.2.3