summaryrefslogtreecommitdiff
path: root/x11-libs/libX11/files/libX11-1.8.2-reentrancy.patch
blob: 784adaeb008fbf3398b4d82714016e5221675a53 (plain)
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
https://gitlab.freedesktop.org/xorg/lib/libx11/-/commit/a9e845809bcaae22496bc8aa3ca252b410d5f39b
https://bugs.gentoo.org/862115

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] 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>
--- 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)
--- 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;
 }
--- 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;
 		}
--- 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.
--- 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;
 		}
--- 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;
     }
 }
 
GitLab