diff options
author | Matthieu Herrb <matthieu@herrb.eu> | 2022-11-11 18:55:23 +0100 |
---|---|---|
committer | Alan Coopersmith <alan.coopersmith@oracle.com> | 2022-11-19 09:20:00 -0800 |
commit | a9e845809bcaae22496bc8aa3ca252b410d5f39b (patch) | |
tree | 1a24b0966c6770be747fa603b4b01d6281d99aa4 | |
parent | bccd787a565d3a88673bfc06574c1939f98d8d72 (diff) | |
download | xorg-lib-libX11-a9e845809bcaae22496bc8aa3ca252b410d5f39b.tar.gz |
Fix 797755 Allow X*IfEvent() to reenter libX11
- the activation logic is reversed
- there is also _XInternalLockDisplay() that needs protection
- I've found cases (in fvwm2) where the callback calls XCheckIfEvent()
recursively. So the flag needs to be a counter.
Reviewed-by: Adam Jackson <ajax@redhat.com>
-rw-r--r-- | include/X11/Xlibint.h | 2 | ||||
-rw-r--r-- | src/ChkIfEv.c | 4 | ||||
-rw-r--r-- | src/IfEvent.c | 4 | ||||
-rw-r--r-- | src/OpenDis.c | 2 | ||||
-rw-r--r-- | src/PeekIfEv.c | 4 | ||||
-rw-r--r-- | src/locking.c | 27 |
6 files changed, 30 insertions, 13 deletions
diff --git a/include/X11/Xlibint.h b/include/X11/Xlibint.h index b4275ebd..e20c4833 100644 --- a/include/X11/Xlibint.h +++ b/include/X11/Xlibint.h @@ -207,7 +207,7 @@ struct _XDisplay XIOErrorExitHandler exit_handler; void *exit_handler_data; - Bool in_ifevent; + CARD32 in_ifevent; }; #define XAllocIDs(dpy,ids,n) (*(dpy)->idlist_alloc)(dpy,ids,n) diff --git a/src/ChkIfEv.c b/src/ChkIfEv.c index 327b5eaf..1bbcba5b 100644 --- a/src/ChkIfEv.c +++ b/src/ChkIfEv.c @@ -49,8 +49,8 @@ Bool XCheckIfEvent ( unsigned long qe_serial = 0; int n; /* time through count */ + dpy->in_ifevent++; LockDisplay(dpy); - dpy->in_ifevent = True; prev = NULL; for (n = 3; --n >= 0;) { for (qelt = prev ? prev->next : dpy->head; @@ -80,7 +80,7 @@ Bool XCheckIfEvent ( /* another thread has snatched this event */ prev = NULL; } - dpy->in_ifevent = False; + dpy->in_ifevent--; UnlockDisplay(dpy); return False; } diff --git a/src/IfEvent.c b/src/IfEvent.c index a0aed7e3..593e7acf 100644 --- a/src/IfEvent.c +++ b/src/IfEvent.c @@ -48,8 +48,8 @@ XIfEvent ( register _XQEvent *qelt, *prev; unsigned long qe_serial = 0; + dpy->in_ifevent++; LockDisplay(dpy); - dpy->in_ifevent = True; prev = NULL; while (1) { for (qelt = prev ? prev->next : dpy->head; @@ -60,7 +60,7 @@ XIfEvent ( *event = qelt->event; _XDeq(dpy, prev, qelt); _XStoreEventCookie(dpy, event); - dpy->in_ifevent = False; + dpy->in_ifevent--; UnlockDisplay(dpy); return 0; } diff --git a/src/OpenDis.c b/src/OpenDis.c index e1bc2a30..17dc4cb2 100644 --- a/src/OpenDis.c +++ b/src/OpenDis.c @@ -189,7 +189,7 @@ XOpenDisplay ( dpy->xcmisc_opcode = 0; dpy->xkb_info = NULL; dpy->exit_handler_data = NULL; - dpy->in_ifevent = False; + dpy->in_ifevent = 0; /* * Setup other information in this display structure. diff --git a/src/PeekIfEv.c b/src/PeekIfEv.c index c4e8af0d..7e09c00b 100644 --- a/src/PeekIfEv.c +++ b/src/PeekIfEv.c @@ -49,8 +49,8 @@ XPeekIfEvent ( register _XQEvent *prev, *qelt; unsigned long qe_serial = 0; + dpy->in_ifevent++; LockDisplay(dpy); - dpy->in_ifevent = True; prev = NULL; while (1) { for (qelt = prev ? prev->next : dpy->head; @@ -64,7 +64,7 @@ XPeekIfEvent ( _XStoreEventCookie(dpy, ©); *event = copy; } - dpy->in_ifevent = False; + dpy->in_ifevent--; UnlockDisplay(dpy); return 0; } diff --git a/src/locking.c b/src/locking.c index bdc07011..690b2bf6 100644 --- a/src/locking.c +++ b/src/locking.c @@ -465,17 +465,33 @@ static void _XIfEventLockDisplay( /* assert(dpy->in_ifevent); */ } +static void _XInternalLockDisplay( + Display *dpy, + Bool wskip + XTHREADS_FILE_LINE_ARGS + ); + +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) + 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; - - dpy->lock_fns->lock_display = _XLockDisplay; - dpy->lock_fns->unlock_display = _XUnlockDisplay; - UnlockDisplay(dpy); } static void _XLockDisplay( @@ -507,6 +523,7 @@ static void _XLockDisplay( if (dpy->in_ifevent) { dpy->lock_fns->lock_display = _XIfEventLockDisplay; dpy->lock_fns->unlock_display = _XIfEventUnlockDisplay; + dpy->lock->internal_lock_display = _XIfEventInternalLockDisplay; } } |