diff options
author | Thorsten Wißmann <edu@thorsten-wissmann.de> | 2018-04-15 11:20:23 +0900 |
---|---|---|
committer | Thorsten Wißmann <edu@thorsten-wissmann.de> | 2018-04-15 11:59:07 +0900 |
commit | f18c2da0500df991fd319447cfb33d8649ffc083 (patch) | |
tree | fc32439008746b1be7a130d434c1da98193087b9 | |
parent | 95aac7ce4eda8691d2c985374fee40fee336530d (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.cpp | 4 |
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); } } |