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>
This commit is contained in:
Matthieu Herrb
2022-11-11 18:55:23 +01:00
committed by Alan Coopersmith
parent bccd787a56
commit a9e845809b
6 changed files with 30 additions and 13 deletions

View File

@@ -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)

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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.

View File

@@ -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, &copy);
*event = copy;
}
dpy->in_ifevent = False;
dpy->in_ifevent--;
UnlockDisplay(dpy);
return 0;
}

View File

@@ -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;
}
}