205 lines
5.1 KiB
Diff
205 lines
5.1 KiB
Diff
From eb1c272ab5230d548077b9f59aca4b3457c3a8f8 Mon Sep 17 00:00:00 2001
|
|
From: GaryOderNichts <garyodernichts@gmail.com>
|
|
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 <X11/Xproto.h> /* to declare xEvent */
|
|
#include <X11/XlibConf.h> /* for configured options like XTHREADS */
|
|
|
|
+#ifdef XTHREADS
|
|
+#include <X11/Xthreads.h>
|
|
+#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
|
|
|