summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThorsten Wißmann <edu@thorsten-wissmann.de>2018-04-15 11:20:23 +0900
committerThorsten Wißmann <edu@thorsten-wissmann.de>2018-04-15 11:59:07 +0900
commitf18c2da0500df991fd319447cfb33d8649ffc083 (patch)
treefc32439008746b1be7a130d434c1da98193087b9
parent95aac7ce4eda8691d2c985374fee40fee336530d (diff)
Fix Xlib race conditions in main loop
The Issue --------- In the presence of many herbstclient calls, it happened that select() in the main loop to block. This issue can be triggered with a loop like: for i in {0..1000} ; do herbstclient echo $i ; done But it also occurred during the autostart or in q3terminal.sh. This issue seems to be caused only on recent setups and not before February 2018. Unblocking select() ------------------- If hlwm freezes during the autostart, the select() unblocks on any events from X, e.g. pressing an hlwm keybinding or moving the cursor across a window edge. The Solution ------------ Instead of using XPending() we now flush the buffers manually by XSync() and then read the length of the event queue directly by XQLength(). It seems to me, that the XSync within the while(XQLength()) { ... } fixes this issue, whereas the other changes are just code simplification without changing the program semantics.
-rw-r--r--src/main.cpp4
1 files changed, 3 insertions, 1 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 5608a8ff..cf5b84dc 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1033,12 +1033,14 @@ int main(int argc, char* argv[]) {
if (g_aboutToQuit) {
break;
}
- while (XPending(g_display)) {
+ XSync(g_display, False);
+ while (XQLength(g_display)) {
XNextEvent(g_display, &event);
void (*handler) (XEvent*) = g_default_handler[event.type];
if (handler != NULL) {
handler(&event);
}
+ XSync(g_display, False);
}
}