[Xcb] problem with xcb-based Xlib and multithreaded applications
Francesco Abbate
francesco.bbt at gmail.com
Tue Jan 4 02:25:29 PST 2011
Hi all,
I'm working since some time in a multithreaded application, GSL shell,
where multiples threads can perform operations on the same window. I'm
using the standard Xlib library but, as all of you certainly knows,
many modern linux distributions use the Xlib implementation based on
xcb.
My application adopt a simple scheme to avoid collisions between
threads or race conditions. A lock per window is used, only one thread
polls and treats the incoming events. Other secondary threads can
perform drawing operations on the same window but the locks ensures
that such operations are performed only when the main thread is
waiting for events in a XNextEvent calls. I precise that I call
XInitThreads before opening any connections.
When the xcb-based implementation of libX11 was introduced my
applications began to hang. After investigations it was clear that the
problem was coming from the xcb implementation of X11 that does not
tolerate that a second thread perform drawing requests when another
threads is polling the events using the same connection.
As a workaround for this problem I've introduced two X connection, one
is used by the main threads to poll the events and perform the related
actions while the other connection is used only by other threads when
they want to perform drawing operations. The locks were still used as
before to avoid conflicts between the threads.
Since then I've experienced another problem, it seems that when I
close the X connections I can get a BadDrawable error because some
drawing operations can still be present in the output buffer. It seems
that a solution for this problem is:
- call XSync on the drawing connections to flush all the events and,
only after, close the connection
- perform the same operations, namely XSync + XCloseDisplay, on the
main x connections, the one used by the thread that manage the
incoming X events.
In this way I make sure that all the outgoing drawing operations are
treated and the output buffer is empy when the drawing and main
connections are closed.
My questions are, is it normal that I need to call XSync before
XCloseDisplay to avoid a BadDrawable error ? Is this related to the
xcb implementation on libX11 ? Is this related to the usage of two
separate connections ?
I hope people in this list can help me. In general I'm experiencing
problems like this one since the introduction on a xcb-based libX11.
For the other side the Windows client was working always flawlessy in
all the Windows versions that I've managed to test. I'm wondering if
the xcb introduction to replace a mature library like libX11 was not
done without the necessary verifications required to support existing
multi-threaded applications. This sound ironic to me since xcb is
supposed to be great for multi-threaded applications!! :-)
I hope that, beside my particular problem, the xcb main developers
will say a few words about this kind of problems with multithreaded
applications. I hope that you understand that for many applications is
very difficult to adopt the xcb library directly because it is a low
level library and many higher level functions provided by libX11 are
simply not available. Since an higher level layer around xcb is not
available I believe that many programmers needs to use libX11 and so
you need to ensure that its xcb based implementation is 100%
compliant.
Thanks in advance for your help.
Best regards,
Francesco Abbate
More information about the Xcb
mailing list