diff options
author | Jeremy Huddleston <jeremyhu@freedesktop.org> | 2009-01-16 13:58:20 -0800 |
---|---|---|
committer | Jeremy Huddleston <jeremyhu@freedesktop.org> | 2009-01-16 13:58:20 -0800 |
commit | ca46c01869768a8661a9d8a71493ed5f0760a8ab (patch) | |
tree | 781a985ae1438e10aa8ab73773d1433de52ca86a | |
parent | b33905234025f005819c7e2acd653a3a0ecfeb82 (diff) |
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)
-rw-r--r-- | dix/main.c | 14 | ||||
-rw-r--r-- | 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 <pthread.h> + +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(); @@ -36,11 +36,6 @@ in this Software without prior written authorization from The Open Group. #include <dix-config.h> #endif -#ifdef XQUARTZ -#include <pthread.h> -static pthread_mutex_t miEventQueueMutex = PTHREAD_MUTEX_INITIALIZER; -#endif - # include <X11/X.h> # include <X11/Xmd.h> # include <X11/Xproto.h> @@ -86,6 +81,25 @@ typedef struct _EventQueue { static EventQueueRec miEventQueue; static EventListPtr masterEvents; /* for use in mieqProcessInputEvents */ +#ifdef XQUARTZ +#include <pthread.h> +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; |