summaryrefslogtreecommitdiffstats
path: root/source/x/x11/patch/libX11/eb1c272ab5230d548077b9f59aca4b3457c3a8f8.patch
blob: badc4e5eb20767799477e98917ce6f1aefa64026 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
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