Comment 52 for bug 194029

Revision history for this message
Mike Stroyan (stroyan) wrote :

This problem with synergyc is actually synergy's own defect related to using X11 from multiple threads.
The connection to the kernel schedule is seen because a race condition in the application is turning
out badly more often than it used to. But the right fix for this problem is in synergy.

I just added this fix as a comment to the upstream report at
http://sourceforge.net/tracker/index.php?func=detail&aid=1930587&group_id=59275&atid=490467

This problem is caused by a bad assumption in the use of poll or select
on the X11 socket connection when waiting for an event in
CXWindowsEventQueueBuffer::waitForEvent*().
The assumption is that any new event will wake the thread when
the socket becomes ready to read. The flaw in that reasoning is that
Xlib will read the data for several events at once if it is available.
The calls to XSendEvent and XFlush in CXWindowsEventQueueBuffer::flush
can read data from the X11 socket and put it in an Xlib buffer. That will
change the XPending and isEmpty status without ever finishing the poll
or select call. The flush function can be called either from another
thread via addEvent or in the direct call to flush in waitForEvent
itself. The severity of these problems will vary greatly with changes
to the scheduling of threads and the X server. It is not surprising
that they show up more often with some kernels than with others.

The attached diffs fix the two cases. The call to flush in waitForEvent
is followed by a new call to isEmpty to check if the flush caused any
events to be read. The call to flush in addEvent is followed by writing
a character to the write side of a pipe. The poll or select call in
waitForEvent then waits for a readable state on either the X11 socket
or the pipe.