Hello, I encounter the following situation on my system reproduceably when I run the synergy KVM switching software (server side).
Thread A is stuck in this call path: XSync() _XReply() // line 625 ff: wait for event_waiter to process first event while(dpy->xcb->event_waiter) { /* need braces around ConditionWait */ ConditionWait(dpy, dpy->xcb->event_notify); } I observe that this thread never leaves this while loop any more. Thread B executes: XIfEvent() _XReadEvents() Until the event it's waiting for arrives, XIfEvent() calls _XReadEvents() in a loop with the display lock held. _XReadEvents() only releases the lock after setting dpy->xcb->event_waiter. Only after re-acquiring the lock, it clears event_waiter and sends a broadcast for the condition variable dpy->xcb->event_notify. In this situation, thread A is effectively blocked: ConditionWait() receives the broadcast, but before it can acquire the display lock and return, _XReadEvents() will have set event_waiter once more, so it needs to wait again. This goes on forever unless the event XIfEvent() is waiting for arrives. In some situations, this seems to take a forever too, I'm not sure why (maybe we are looking at a deadlock situation here in the sense that the expected condition can't happen unless thread A gets a chance to run). I am attaching a tentative patch that I've come up with. Please review it. The rationale is to yield to a request waiter after grabbing one event. I am currently testing it on my system (too early to come to a conclusion though, at least it doesn't seem to have caused a regression so far). CC'ing Jamey who seems to be the expert on XCB locking matters. The thread https://groups.google.com/forum/#!topic/synergy-users/4O_Xod9HV-A suggests that other people are seeing the same problem. It also suggests that this only occurs wiht recent versions of synergy. However, IMO the above analysis rather indicates a general XCB problem. Please comment. Regards Martin
--- libX11-1.6.3/src/xcb_io.c 2015-03-09 23:28:45.000000000 +0100 +++ libX11-1.6.3mw/src/xcb_io.c 2016-07-20 08:59:17.676070822 +0200 @@ -424,12 +424,15 @@ response = poll_for_response(dpy); if(response) handle_response(dpy, response, False); - else if(dpy->xcb->pending_requests->reply_waiter) + else if(!dpy->xcb->pending_requests->reply_waiter) + _XIOError(dpy); + + /* If there is a reply waiter, give him a chance to run. */ + + if(dpy->xcb->pending_requests && dpy->xcb->pending_requests->reply_waiter) { /* need braces around ConditionWait */ ConditionWait(dpy, dpy->xcb->reply_notify); } - else - _XIOError(dpy); } /* The preceding loop established that there is no
_______________________________________________ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel