From eb1c272ab5230d548077b9f59aca4b3457c3a8f8 Mon Sep 17 00:00:00 2001 From: GaryOderNichts Date: Sat, 17 Dec 2022 16:28:40 +0100 Subject: [PATCH] Fix a9e845 and 797755 Allow X*IfEvent() to reenter libX11 --- include/X11/Xlibint.h | 9 +++++- src/ChkIfEv.c | 5 +++- src/IfEvent.c | 5 +++- src/PeekIfEv.c | 5 +++- src/locking.c | 65 +++++++++---------------------------------- 5 files changed, 33 insertions(+), 56 deletions(-) diff --git a/include/X11/Xlibint.h b/include/X11/Xlibint.h index e20c4833..50099b43 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 b32c2d3e..66636696 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 54c37f00..35c592e3 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 68c028b7..754749a7 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 c550603e..3625bd27 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 || !xthread_equal(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 && xthread_equal(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 && xthread_equal(dpy->ifevent_thread, xthread_self())) + return; + #ifdef XTHREADS_WARN _XLockDisplayWarn(dpy, file, line); #else -- GitLab