The EventsLoop on X11 backend uses XNextEvent to poll and wait for events which is not thread safe.
XNextEvent will hold the global Xlib mutex while blocked waiting for input, which causes a deadlock when other threads try to use X11, e.g. when calling make_current for a GL context.
The workaround is to use select or poll to wait for input on the X11 socket file descriptor and then use a non-blocking function like XCheckIfEvent to grab the events from the event queue. This is a rather ugly workaround to an ugly Xlib limitation.
Here is my work-in-progress fix to this problem: https://github.com/rikusalminen/winit/tree/waitevent
This patch is not quite complete and I'm seeing some strange issues with CloseRequested events which I can't quite explain. Some further debugging is required. Any help with testing and debugging is welcome. edit: fixed!
This bug also introduces an error handling conondrum. XNextEvent and other X11 functions do not return an error code, but poll will return error codes, some of which may be fatal errors. EventsLoop::runForever does not return a Result or other error code. I don't know what the right solution is (which would be compatible with other backend). Please advice how to proceed with this. edit: solved with assert! and panic! for fatal error conditions.
Additionally, a multi-threaded example/test case would be useful to verify that this problem is solved.
This issue is the root cause in several open issues for winit. At least the following bugs look like they are caused by this: #757, #420, #239 .
NOTE: I also fixed this same issue in GLFW back in 2012:
glfw/glfw@3d6221c#diff-0f3106b1408d89cbecbe2f57a783331b
The
EventsLoopon X11 backend usesXNextEventto poll and wait for events which is not thread safe.XNextEventwill hold the global Xlib mutex while blocked waiting for input, which causes a deadlock when other threads try to use X11, e.g. when callingmake_currentfor a GL context.The workaround is to use
selectorpollto wait for input on the X11 socket file descriptor and then use a non-blocking function likeXCheckIfEventto grab the events from the event queue. This is a rather ugly workaround to an ugly Xlib limitation.Here is my work-in-progress fix to this problem: https://github.com/rikusalminen/winit/tree/waitevent
This patch is not quite complete and I'm seeing some strange issues withedit: fixed!CloseRequestedevents which I can't quite explain. Some further debugging is required. Any help with testing and debugging is welcome.This bug also introduces an error handling conondrum.edit: solved withXNextEventand other X11 functions do not return an error code, butpollwill return error codes, some of which may be fatal errors.EventsLoop::runForeverdoes not return aResultor other error code. I don't know what the right solution is (which would be compatible with other backend). Please advice how to proceed with this.assert!andpanic!for fatal error conditions.Additionally, a multi-threaded example/test case would be useful to verify that this problem is solved.
This issue is the root cause in several open issues for winit. At least the following bugs look like they are caused by this: #757, #420, #239 .
NOTE: I also fixed this same issue in GLFW back in 2012:
glfw/glfw@3d6221c#diff-0f3106b1408d89cbecbe2f57a783331b