diff options
author | Jeremy Huddleston <jeremyhu@freedesktop.org> | 2008-04-17 15:23:00 -0700 |
---|---|---|
committer | Jeremy Huddleston <jeremyhu@freedesktop.org> | 2008-04-17 15:24:35 -0700 |
commit | 2a1ba20af98c0e9a6a7f1a50d32058dcc9759c21 (patch) | |
tree | 88d1c9cc40c0f159b55fbde83bb7a7a09c0ada3c | |
parent | 55f80d754525398378de1ef28aa562bd29ee750f (diff) |
XQuartz: Use a mutex to ensure we only have one thread calling mieqEnqueue at a time.
(cherry picked from commit 7b087c965bce9f440ab5233d6383aa4a7de969b8)
-rw-r--r-- | hw/xquartz/darwinEvents.c | 246 | ||||
-rw-r--r-- | hw/xquartz/darwinEvents.h | 1 | ||||
-rw-r--r-- | hw/xquartz/threadSafety.c | 2 | ||||
-rw-r--r-- | hw/xquartz/threadSafety.h | 3 |
4 files changed, 149 insertions, 103 deletions
diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c index 260690ce5..c59359625 100644 --- a/hw/xquartz/darwinEvents.c +++ b/hw/xquartz/darwinEvents.c @@ -54,6 +54,9 @@ in this Software without prior written authorization from The Open Group. #include <sys/types.h> #include <sys/uio.h> #include <unistd.h> +#include <pthread.h> +#include <errno.h> + #include <IOKit/hidsystem/IOLLEvent.h> /* Fake button press/release for scroll wheel move. */ @@ -77,6 +80,25 @@ static int old_flags = 0; // last known modifier state xEvent *darwinEvents = NULL; +pthread_mutex_t mieqEnqueue_mutex; +static inline void mieqEnqueue_lock(void) { + int err; + if((err = pthread_mutex_lock(&mieqEnqueue_mutex))) { + ErrorF("%s:%s:%d: Failed to lock mieqEnqueue_mutex: %d\n", + __FILE__, __FUNCTION__, __LINE__, err); + spewCallStack(); + } +} + +static inline void mieqEnqueue_unlock(void) { + int err; + if((err = pthread_mutex_unlock(&mieqEnqueue_mutex))) { + ErrorF("%s:%s:%d: Failed to unlock mieqEnqueue_mutex: %d\n", + __FILE__, __FUNCTION__, __LINE__, err); + spewCallStack(); + } +} + /* * DarwinPressModifierMask * Press or release the given modifier key, specified by its mask. @@ -197,107 +219,119 @@ static void DarwinSimulateMouseClick( mieqSetHandler. */ void DarwinEventHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, int nevents) { - int i; - - DEBUG_LOG("DarwinEventHandler(%d, %p, %p, %d)\n", screenNum, xe, dev, nevents); - for (i=0; i<nevents; i++) { - switch(xe[i].u.u.type) { - case kXquartzControllerNotify: - DEBUG_LOG("kXquartzControllerNotify\n"); - AppleWMSendEvent(AppleWMControllerNotify, - AppleWMControllerNotifyMask, - xe[i].u.clientMessage.u.l.longs0, - xe[i].u.clientMessage.u.l.longs1); - break; - - case kXquartzPasteboardNotify: - DEBUG_LOG("kXquartzPasteboardNotify\n"); - AppleWMSendEvent(AppleWMPasteboardNotify, - AppleWMPasteboardNotifyMask, - xe[i].u.clientMessage.u.l.longs0, - xe[i].u.clientMessage.u.l.longs1); - break; - - case kXquartzActivate: - DEBUG_LOG("kXquartzActivate\n"); - QuartzShow(xe[i].u.keyButtonPointer.rootX, - xe[i].u.keyButtonPointer.rootY); - AppleWMSendEvent(AppleWMActivationNotify, - AppleWMActivationNotifyMask, - AppleWMIsActive, 0); - break; - - case kXquartzDeactivate: - DEBUG_LOG("kXquartzDeactivate\n"); - DarwinReleaseModifiers(); - AppleWMSendEvent(AppleWMActivationNotify, - AppleWMActivationNotifyMask, - AppleWMIsInactive, 0); - QuartzHide(); - break; - - case kXquartzWindowState: - DEBUG_LOG("kXquartzWindowState\n"); - RootlessNativeWindowStateChanged(xprGetXWindow(xe[i].u.clientMessage.u.l.longs0), - xe[i].u.clientMessage.u.l.longs1); - break; - - case kXquartzWindowMoved: - DEBUG_LOG("kXquartzWindowMoved\n"); - RootlessNativeWindowMoved ((WindowPtr)xe[i].u.clientMessage.u.l.longs0); - break; - - case kXquartzToggleFullscreen: - DEBUG_LOG("kXquartzToggleFullscreen\n"); + int i; + + TA_SERVER(); + + DEBUG_LOG("DarwinEventHandler(%d, %p, %p, %d)\n", screenNum, xe, dev, nevents); + for (i=0; i<nevents; i++) { + switch(xe[i].u.u.type) { + case kXquartzControllerNotify: + DEBUG_LOG("kXquartzControllerNotify\n"); + AppleWMSendEvent(AppleWMControllerNotify, + AppleWMControllerNotifyMask, + xe[i].u.clientMessage.u.l.longs0, + xe[i].u.clientMessage.u.l.longs1); + break; + + case kXquartzPasteboardNotify: + DEBUG_LOG("kXquartzPasteboardNotify\n"); + AppleWMSendEvent(AppleWMPasteboardNotify, + AppleWMPasteboardNotifyMask, + xe[i].u.clientMessage.u.l.longs0, + xe[i].u.clientMessage.u.l.longs1); + break; + + case kXquartzActivate: + DEBUG_LOG("kXquartzActivate\n"); + QuartzShow(xe[i].u.keyButtonPointer.rootX, + xe[i].u.keyButtonPointer.rootY); + AppleWMSendEvent(AppleWMActivationNotify, + AppleWMActivationNotifyMask, + AppleWMIsActive, 0); + break; + + case kXquartzDeactivate: + DEBUG_LOG("kXquartzDeactivate\n"); + DarwinReleaseModifiers(); + AppleWMSendEvent(AppleWMActivationNotify, + AppleWMActivationNotifyMask, + AppleWMIsInactive, 0); + QuartzHide(); + break; + + case kXquartzWindowState: + DEBUG_LOG("kXquartzWindowState\n"); + RootlessNativeWindowStateChanged(xprGetXWindow(xe[i].u.clientMessage.u.l.longs0), + xe[i].u.clientMessage.u.l.longs1); + break; + + case kXquartzWindowMoved: + DEBUG_LOG("kXquartzWindowMoved\n"); + RootlessNativeWindowMoved ((WindowPtr)xe[i].u.clientMessage.u.l.longs0); + break; + + case kXquartzToggleFullscreen: + DEBUG_LOG("kXquartzToggleFullscreen\n"); #ifdef DARWIN_DDX_MISSING - if (quartzEnableRootless) QuartzSetFullscreen(!quartzHasRoot); - else if (quartzHasRoot) QuartzHide(); - else QuartzShow(); + if (quartzEnableRootless) + QuartzSetFullscreen(!quartzHasRoot); + else if (quartzHasRoot) + QuartzHide(); + else + QuartzShow(); #else - // ErrorF("kXquartzToggleFullscreen not implemented\n"); + // ErrorF("kXquartzToggleFullscreen not implemented\n"); #endif - break; - - case kXquartzSetRootless: - DEBUG_LOG("kXquartzSetRootless\n"); + break; + + case kXquartzSetRootless: + DEBUG_LOG("kXquartzSetRootless\n"); #ifdef DARWIN_DDX_MISSING - QuartzSetRootless(xe[i].u.clientMessage.u.l.longs0); - if (!quartzEnableRootless && !quartzHasRoot) QuartzHide(); + QuartzSetRootless(xe[i].u.clientMessage.u.l.longs0); + if (!quartzEnableRootless && !quartzHasRoot) + QuartzHide(); #else - // ErrorF("kXquartzSetRootless not implemented\n"); + // ErrorF("kXquartzSetRootless not implemented\n"); #endif - break; - - case kXquartzSetRootClip: - QuartzSetRootClip((BOOL)xe[i].u.clientMessage.u.l.longs0); - break; - - case kXquartzQuit: - GiveUp(0); - break; - - case kXquartzBringAllToFront: - DEBUG_LOG("kXquartzBringAllToFront\n"); - RootlessOrderAllWindows(); - break; - - case kXquartzSpaceChanged: - DEBUG_LOG("kXquartzSpaceChanged\n"); - QuartzSpaceChanged(xe[i].u.clientMessage.u.l.longs0); - - break; - default: - ErrorF("Unknown application defined event type %d.\n", xe[i].u.u.type); + break; + + case kXquartzSetRootClip: + QuartzSetRootClip((BOOL)xe[i].u.clientMessage.u.l.longs0); + break; + + case kXquartzQuit: + GiveUp(0); + break; + + case kXquartzBringAllToFront: + DEBUG_LOG("kXquartzBringAllToFront\n"); + RootlessOrderAllWindows(); + break; + + case kXquartzSpaceChanged: + DEBUG_LOG("kXquartzSpaceChanged\n"); + QuartzSpaceChanged(xe[i].u.clientMessage.u.l.longs0); + break; + + default: + ErrorF("Unknown application defined event type %d.\n", xe[i].u.u.type); } - } + } } Bool DarwinEQInit(DevicePtr pKbd, DevicePtr pPtr) { + int err; + if (!darwinEvents) darwinEvents = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum()); if (!darwinEvents) FatalError("Couldn't allocate event buffer\n"); + if((err = pthread_mutex_init(&mieqEnqueue_mutex, NULL))) { + FatalError("Couldn't allocate miEnqueue mutex: %d.\n", err); + } + mieqInit(); mieqSetHandler(kXquartzReloadKeymap, DarwinKeyboardReloadHandler); mieqSetHandler(kXquartzActivate, DarwinEventHandler); @@ -305,7 +339,7 @@ Bool DarwinEQInit(DevicePtr pKbd, DevicePtr pPtr) { mieqSetHandler(kXquartzSetRootClip, DarwinEventHandler); mieqSetHandler(kXquartzQuit, DarwinEventHandler); mieqSetHandler(kXquartzReadPasteboard, QuartzReadPasteboard); - mieqSetHandler(kXquartzWritePasteboard, QuartzWritePasteboard); + mieqSetHandler(kXquartzWritePasteboard, QuartzWritePasteboard); mieqSetHandler(kXquartzToggleFullscreen, DarwinEventHandler); mieqSetHandler(kXquartzSetRootless, DarwinEventHandler); mieqSetHandler(kXquartzSpaceChanged, DarwinEventHandler); @@ -325,6 +359,8 @@ Bool DarwinEQInit(DevicePtr pKbd, DevicePtr pPtr) { void ProcessInputEvents(void) { xEvent xe; int x = sizeof(xe); + + TA_SERVER(); mieqProcessInputEvents(); @@ -336,7 +372,7 @@ void ProcessInputEvents(void) { /* Sends a null byte down darwinEventWriteFD, which will cause the Dispatch() event loop to check out event queue */ -void DarwinPokeEQ(void) { +static void DarwinPokeEQ(void) { char nullbyte=0; input_check_flag++; // <daniels> oh, i ... er ... christ. @@ -398,15 +434,18 @@ void DarwinSendPointerEvents(int ev_type, int ev_button, int pointer_x, int poin return; } - num_events = GetPointerEvents(darwinEvents, darwinPointer, ev_type, ev_button, - POINTER_ABSOLUTE, 0, 5, valuators); - - for(i=0; i<num_events; i++) mieqEnqueue (darwinPointer,&darwinEvents[i]); - DarwinPokeEQ(); + mieqEnqueue_lock(); { + num_events = GetPointerEvents(darwinEvents, darwinPointer, ev_type, ev_button, + POINTER_ABSOLUTE, 0, 5, valuators); + for(i=0; i<num_events; i++) mieqEnqueue (darwinPointer,&darwinEvents[i]); + DarwinPokeEQ(); + + } mieqEnqueue_unlock(); } void DarwinSendKeyboardEvents(int ev_type, int keycode) { int i, num_events; + if(!darwinEvents) { ErrorF("DarwinSendKeyboardEvents called before darwinEvents was initialized\n"); return; @@ -425,9 +464,11 @@ void DarwinSendKeyboardEvents(int ev_type, int keycode) { } } - num_events = GetKeyboardEvents(darwinEvents, darwinKeyboard, ev_type, keycode + MIN_KEYCODE); - for(i=0; i<num_events; i++) mieqEnqueue(darwinKeyboard,&darwinEvents[i]); - DarwinPokeEQ(); + mieqEnqueue_lock(); { + num_events = GetKeyboardEvents(darwinEvents, darwinKeyboard, ev_type, keycode + MIN_KEYCODE); + for(i=0; i<num_events; i++) mieqEnqueue(darwinKeyboard,&darwinEvents[i]); + DarwinPokeEQ(); + } mieqEnqueue_unlock(); } void DarwinSendProximityEvents(int ev_type, int pointer_x, int pointer_y, @@ -443,11 +484,12 @@ void DarwinSendProximityEvents(int ev_type, int pointer_x, int pointer_y, return; } - num_events = GetProximityEvents(darwinEvents, darwinPointer, ev_type, - 0, 5, valuators); - - for(i=0; i<num_events; i++) mieqEnqueue (darwinPointer,&darwinEvents[i]); - DarwinPokeEQ(); + mieqEnqueue_lock(); { + num_events = GetProximityEvents(darwinEvents, darwinPointer, ev_type, + 0, 5, valuators); + for(i=0; i<num_events; i++) mieqEnqueue (darwinPointer,&darwinEvents[i]); + DarwinPokeEQ(); + } mieqEnqueue_unlock(); } @@ -512,5 +554,7 @@ void DarwinSendDDXEvent(int type, int argc, ...) { va_end (args); } + mieqEnqueue_lock(); mieqEnqueue(darwinPointer, &xe); + mieqEnqueue_unlock(); } diff --git a/hw/xquartz/darwinEvents.h b/hw/xquartz/darwinEvents.h index 98426d6ee..c87d667f9 100644 --- a/hw/xquartz/darwinEvents.h +++ b/hw/xquartz/darwinEvents.h @@ -32,7 +32,6 @@ Bool DarwinEQInit(DevicePtr pKbd, DevicePtr pPtr); void DarwinEQEnqueue(const xEventPtr e); void DarwinEQPointerPost(DeviceIntPtr pDev, xEventPtr e); void DarwinEQSwitchScreen(ScreenPtr pScreen, Bool fromDIX); -void DarwinPokeEQ(void); void DarwinSendPointerEvents(int ev_type, int ev_button, int pointer_x, int pointer_y, float pressure, float tilt_x, float tilt_y); void DarwinSendProximityEvents(int ev_type, int pointer_x, int pointer_y, diff --git a/hw/xquartz/threadSafety.c b/hw/xquartz/threadSafety.c index c0ec1e4e6..7835de68d 100644 --- a/hw/xquartz/threadSafety.c +++ b/hw/xquartz/threadSafety.c @@ -36,7 +36,7 @@ pthread_t SERVER_THREAD; pthread_t APPKIT_THREAD; -static inline void spewCallStack(void) { +void spewCallStack(void) { void* callstack[128]; int i, frames = backtrace(callstack, 128); char** strs = backtrace_symbols(callstack, frames); diff --git a/hw/xquartz/threadSafety.h b/hw/xquartz/threadSafety.h index da3b5992e..ed2ad9ff5 100644 --- a/hw/xquartz/threadSafety.h +++ b/hw/xquartz/threadSafety.h @@ -36,6 +36,9 @@ extern pthread_t APPKIT_THREAD; #define threadSafetyID(tid) (pthread_equal((tid), SERVER_THREAD) ? "X Server Thread" : "Appkit Thread") +/* Dump the call stack */ +void spewCallStack(void); + /* Print message to ErrorF if we're in the wrong thread */ void _threadAssert(pthread_t tid, const char *file, const char *fun, int line); |