diff options
author | Jeremy Huddleston <jeremyhu@freedesktop.org> | 2009-01-11 01:56:45 -0800 |
---|---|---|
committer | Jeremy Huddleston <jeremyhu@freedesktop.org> | 2009-01-11 01:56:45 -0800 |
commit | 5339c22a8ca8bce6cd2b51e97c904292e7c40e74 (patch) | |
tree | 591d4eb4bc541f6f7fa594e2f07332e58617d8f4 | |
parent | 1beff89810cd193e45d437846929b3938cee6d96 (diff) |
XQuartz: Add locking to make mieq thread safe on OSX
(cherry picked from commit 7a8d2266861e74176b5310b83652a9c10a170494)
-rw-r--r-- | hw/xquartz/darwinEvents.c | 3 | ||||
-rw-r--r-- | mi/mieq.c | 54 | ||||
-rw-r--r-- | mi/mipointer.c | 12 |
3 files changed, 68 insertions, 1 deletions
diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c index 9a9483181..0d864db97 100644 --- a/hw/xquartz/darwinEvents.c +++ b/hw/xquartz/darwinEvents.c @@ -115,7 +115,8 @@ void darwinEvents_lock(void) { } } -static inline void darwinEvents_unlock(void) { +void darwinEvents_unlock(void); +void darwinEvents_unlock(void) { int err; if((err = pthread_mutex_unlock(&mieq_lock))) { ErrorF("%s:%s:%d: Failed to unlock mieq_lock: %d\n", @@ -36,6 +36,11 @@ 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> @@ -138,6 +143,9 @@ mieqEnqueue(DeviceIntPtr pDev, xEvent *e) int isMotion = 0; int evlen; +#ifdef XQUARTZ + pthread_mutex_lock(&miEventQueueMutex); +#endif /* avoid merging events from different devices */ if (e->u.u.type == MotionNotify) @@ -156,6 +164,10 @@ mieqEnqueue(DeviceIntPtr pDev, xEvent *e) lastkbp = (deviceKeyButtonPointer *) laste->events->event; if (laste->nevents > 6) { +#ifdef XQUARTZ + pthread_mutex_unlock(&miEventQueueMutex); +#endif + ErrorF("[mi] mieqEnqueue: more than six valuator events; dropping.\n"); return; } @@ -167,11 +179,17 @@ mieqEnqueue(DeviceIntPtr pDev, xEvent *e) lastkbp->type == ProximityOut) || ((lastkbp->deviceid & DEVICE_BITS) != (v->deviceid & DEVICE_BITS))) { +#ifdef XQUARTZ + pthread_mutex_unlock(&miEventQueueMutex); +#endif ErrorF("[mi] mieqEnequeue: out-of-order valuator event; dropping.\n"); return; } memcpy((laste->events[laste->nevents++].event), e, sizeof(xEvent)); +#ifdef XQUARTZ + pthread_mutex_unlock(&miEventQueueMutex); +#endif return; } @@ -191,6 +209,9 @@ mieqEnqueue(DeviceIntPtr pDev, xEvent *e) xorg_backtrace(); stuck = 1; } +#ifdef XQUARTZ + pthread_mutex_unlock(&miEventQueueMutex); +#endif return; } stuck = 0; @@ -208,6 +229,9 @@ mieqEnqueue(DeviceIntPtr pDev, xEvent *e) if (!evt->event) { ErrorF("[mi] Running out of memory. Tossing event.\n"); +#ifdef XQUARTZ + pthread_mutex_unlock(&miEventQueueMutex); +#endif return; } } @@ -228,24 +252,39 @@ mieqEnqueue(DeviceIntPtr pDev, xEvent *e) miEventQueue.lastMotion = isMotion; miEventQueue.tail = (oldtail + 1) % QUEUE_SIZE; +#ifdef XQUARTZ + pthread_mutex_unlock(&miEventQueueMutex); +#endif } void mieqSwitchScreen(DeviceIntPtr pDev, ScreenPtr pScreen, Bool fromDIX) { +#ifdef XQUARTZ + pthread_mutex_lock(&miEventQueueMutex); +#endif EnqueueScreen(pDev) = pScreen; if (fromDIX) DequeueScreen(pDev) = pScreen; +#ifdef XQUARTZ + pthread_mutex_unlock(&miEventQueueMutex); +#endif } void mieqSetHandler(int event, mieqHandler handler) { +#ifdef XQUARTZ + pthread_mutex_lock(&miEventQueueMutex); +#endif if (handler && miEventQueue.handlers[event]) ErrorF("[mi] mieq: warning: overriding existing handler %p with %p for " "event %d\n", miEventQueue.handlers[event], handler, event); miEventQueue.handlers[event] = handler; +#ifdef XQUARTZ + pthread_mutex_unlock(&miEventQueueMutex); +#endif } /** @@ -317,6 +356,10 @@ mieqProcessInputEvents(void) DeviceIntPtr dev = NULL, master = NULL; +#ifdef XQUARTZ + pthread_mutex_lock(&miEventQueueMutex); +#endif + while (miEventQueue.head != miEventQueue.tail) { e = &miEventQueue.events[miEventQueue.head]; @@ -340,6 +383,10 @@ mieqProcessInputEvents(void) miEventQueue.head = (miEventQueue.head + 1) % QUEUE_SIZE; +#ifdef XQUARTZ + pthread_mutex_unlock(&miEventQueueMutex); +#endif + type = event->u.u.type; master = (!dev->isMaster && dev->u.master) ? dev->u.master : NULL; @@ -389,6 +436,13 @@ mieqProcessInputEvents(void) /* Update the sprite now. Next event may be from different device. */ if (type == DeviceMotionNotify && (master || dev->isMaster)) miPointerUpdateSprite(dev); + +#ifdef XQUARTZ + pthread_mutex_lock(&miEventQueueMutex); +#endif } +#ifdef XQUARTZ + pthread_mutex_unlock(&miEventQueueMutex); +#endif } diff --git a/mi/mipointer.c b/mi/mipointer.c index 4358759cc..83a355ea3 100644 --- a/mi/mipointer.c +++ b/mi/mipointer.c @@ -547,6 +547,12 @@ miPointerGetPosition(DeviceIntPtr pDev, int *x, int *y) *y = MIPOINTER(pDev)->y; } +#ifdef XQUARTZ +#include <pthread.h> +void darwinEvents_lock(void); +void darwinEvents_unlock(void); +#endif + void miPointerMove (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) { @@ -573,7 +579,13 @@ miPointerMove (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) nevents = GetPointerEvents(events, pDev, MotionNotify, 0, POINTER_ABSOLUTE, 0, 2, valuators); OsBlockSignals(); +#ifdef XQUARTZ + darwinEvents_lock(); +#endif for (i = 0; i < nevents; i++) mieqEnqueue(pDev, events[i].event); +#ifdef XQUARTZ + darwinEvents_unlock(); +#endif OsReleaseSignals(); } |