libX11/U_0003-Fix-797755-Allow-X-IfEvent-to-reenter-libX11.patch
Stefan Dirsch e17a686d68 - U_0001-Add-XFreeThreads-function.patch
U_0002-Don-t-use-pragma-inside-a-function-it-breaks-compili.patch
  U_0003-Fix-797755-Allow-X-IfEvent-to-reenter-libX11.patch
  U_0004-Indentation-fixes-around-recent-dpy-in_ifevent-chang.patch
  U_0005-ChkIfEv.c-fix-wrong-handling-of-dpy-in_ifevent.patch
  * adding all patches since 1.8.2 release in order to try fixing
    regressions after introducing thread safety constructor with
    1.8.1 (boo#1205778, boo#1205818)
- supersedes U_Fix-797755-Allow-X-IfEvent-to-reenter-libX11.patch
- re-enabled thread safe constructor

OBS-URL: https://build.opensuse.org/package/show/X11:XOrg/libX11?expand=0&rev=91
2022-12-03 10:31:33 +00:00

170 lines
4.6 KiB
Diff

From a9e845809bcaae22496bc8aa3ca252b410d5f39b Mon Sep 17 00:00:00 2001
From: Matthieu Herrb <matthieu@herrb.eu>
Date: Fri, 11 Nov 2022 18:55:23 +0100
Subject: [PATCH 3/5] 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>
---
include/X11/Xlibint.h | 2 +-
src/ChkIfEv.c | 4 ++--
src/IfEvent.c | 4 ++--
src/OpenDis.c | 2 +-
src/PeekIfEv.c | 4 ++--
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, &copy);
*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;
}
}
--
2.35.3