diff --git a/include/X11/Xlibint.h b/include/X11/Xlibint.h index e20c4833c16c6d3518e4b7feb9bdbc606584bfcc..b570bd01c657f4d86f06b414a43e96da4319f729 100644 --- a/include/X11/Xlibint.h +++ b/include/X11/Xlibint.h @@ -43,6 +43,10 @@ from The Open Group. #include /* to declare xEvent */ #include /* for configured options like XTHREADS */ +#ifdef XTHREADS +#include +#endif + /* The Xlib structs are full of implicit padding to properly align members. We can't clean that up without breaking ABI, so tell clang not to bother complaining about it. */ @@ -207,7 +211,10 @@ struct _XDisplay XIOErrorExitHandler exit_handler; void *exit_handler_data; - CARD32 in_ifevent; + CARD32 in_ifevent; +#ifdef XTHREADS + xthread_t ifevent_thread; +#endif }; #define XAllocIDs(dpy,ids,n) (*(dpy)->idlist_alloc)(dpy,ids,n) diff --git a/src/ChkIfEv.c b/src/ChkIfEv.c index b32c2d3ebcb1aad0e704a3e5dce52dc31971afd2..666366966a0e81bf413a64e015a84da1fcf5cdf0 100644 --- a/src/ChkIfEv.c +++ b/src/ChkIfEv.c @@ -49,8 +49,11 @@ Bool XCheckIfEvent ( unsigned long qe_serial = 0; int n; /* time through count */ - dpy->in_ifevent++; LockDisplay(dpy); +#ifdef XTHREADS + dpy->ifevent_thread = xthread_self(); +#endif + dpy->in_ifevent++; prev = NULL; for (n = 3; --n >= 0;) { for (qelt = prev ? prev->next : dpy->head; diff --git a/src/IfEvent.c b/src/IfEvent.c index 54c37f0031b27f3d7eb629ec2ea16b615b29e734..35c592e3a54d89f1d2ac1efa40c43a04eab1c0c5 100644 --- a/src/IfEvent.c +++ b/src/IfEvent.c @@ -48,8 +48,11 @@ XIfEvent ( register _XQEvent *qelt, *prev; unsigned long qe_serial = 0; - dpy->in_ifevent++; LockDisplay(dpy); +#ifdef XTHREADS + dpy->ifevent_thread = xthread_self(); +#endif + dpy->in_ifevent++; prev = NULL; while (1) { for (qelt = prev ? prev->next : dpy->head; diff --git a/src/PeekIfEv.c b/src/PeekIfEv.c index 68c028b70705968c6757c1e70a238886a94adecb..754749a77c0835c0ba3c1aa6edded15dab7fb478 100644 --- a/src/PeekIfEv.c +++ b/src/PeekIfEv.c @@ -49,8 +49,11 @@ XPeekIfEvent ( register _XQEvent *prev, *qelt; unsigned long qe_serial = 0; - dpy->in_ifevent++; LockDisplay(dpy); +#ifdef XTHREADS + dpy->ifevent_thread = xthread_self(); +#endif + dpy->in_ifevent++; prev = NULL; while (1) { for (qelt = prev ? prev->next : dpy->head; diff --git a/src/locking.c b/src/locking.c index c550603e1f5d0601af3fa19c0b8486ef5b1bc30f..642cf9894268dfbbb79a104b42b4097cfd293d82 100644 --- a/src/locking.c +++ b/src/locking.c @@ -240,7 +240,9 @@ static void _XUnlockDisplay( if (lock_hist_loc >= LOCK_HIST_SIZE) lock_hist_loc = 0; #endif /* XTHREADS_WARN */ - xmutex_unlock(dpy->lock->mutex); + + if (dpy->in_ifevent == 0 || dpy->ifevent_thread != xthread_self()) + xmutex_unlock(dpy->lock->mutex); } @@ -453,63 +455,24 @@ static void _XDisplayLockWait( } static void _XLockDisplay( - Display *dpy - XTHREADS_FILE_LINE_ARGS - ); - -static void _XIfEventLockDisplay( Display *dpy XTHREADS_FILE_LINE_ARGS ) { - /* assert(dpy->in_ifevent); */ -} + struct _XErrorThreadInfo *ti; -static void _XInternalLockDisplay( - Display *dpy, - Bool wskip - XTHREADS_FILE_LINE_ARGS - ); + if (dpy->in_ifevent && dpy->ifevent_thread == xthread_self()) + return; -static void _XIfEventInternalLockDisplay( - Display *dpy, - Bool wskip - XTHREADS_FILE_LINE_ARGS - ) -{ - /* assert(dpy->in_ifevent); */ -} - -static void _XIfEventUnlockDisplay( - Display *dpy - XTHREADS_FILE_LINE_ARGS - ) -{ - if (dpy->in_ifevent == 0) { - dpy->lock_fns->lock_display = _XLockDisplay; - dpy->lock_fns->unlock_display = _XUnlockDisplay; - dpy->lock->internal_lock_display = _XInternalLockDisplay; - UnlockDisplay(dpy); - } else - return; -} - -static void _XLockDisplay( - Display *dpy - XTHREADS_FILE_LINE_ARGS - ) -{ -#ifdef XTHREADS - struct _XErrorThreadInfo *ti; -#endif #ifdef XTHREADS_WARN _XLockDisplayWarn(dpy, file, line); #else xmutex_lock(dpy->lock->mutex); #endif + if (dpy->lock->locking_level > 0) - _XDisplayLockWait(dpy); -#ifdef XTHREADS + _XDisplayLockWait(dpy); + /* * Skip the two function calls below which may generate requests * when LockDisplay is called from within _XError. @@ -517,14 +480,9 @@ static void _XLockDisplay( for (ti = dpy->error_threads; ti; ti = ti->next) if (ti->error_thread == xthread_self()) return; -#endif + _XIDHandler(dpy); _XSeqSyncFunction(dpy); - if (dpy->in_ifevent) { - dpy->lock_fns->lock_display = _XIfEventLockDisplay; - dpy->lock_fns->unlock_display = _XIfEventUnlockDisplay; - dpy->lock->internal_lock_display = _XIfEventInternalLockDisplay; - } } /* @@ -537,6 +495,9 @@ static void _XInternalLockDisplay( XTHREADS_FILE_LINE_ARGS ) { + if (dpy->in_ifevent && dpy->ifevent_thread == xthread_self()) + return; + #ifdef XTHREADS_WARN _XLockDisplayWarn(dpy, file, line); #else