summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Huddleston <jeremyhu@freedesktop.org>2009-01-16 13:58:20 -0800
committerJeremy Huddleston <jeremyhu@freedesktop.org>2009-01-16 13:58:20 -0800
commitca46c01869768a8661a9d8a71493ed5f0760a8ab (patch)
tree781a985ae1438e10aa8ab73773d1433de52ca86a
parentb33905234025f005819c7e2acd653a3a0ecfeb82 (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.c14
-rw-r--r--mi/mieq.c34
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();
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 <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;