[Xcb] Xlib/XCB in multi-threaded situation results in deadlock

Joris Dobbelsteen joris.dobbelsteen at sioux.eu
Wed Dec 1 07:29:38 PST 2010


We have been using DirectFB 1.4.7 with it's X11 backend, which uses
Xlib/XCB. The DirectFB library performs receiving the input
(keyboard/mouse) events on a separate thread from the drawing.
This has resulted in a call to DRI2GetBuffersWithFormat getting stuck,
while the other thread is trying to receive a mouse event. Once the
mouse moves the program moves forward for a short while.

It seems that the drawing thread is suck on the poll and waiting for a
reply, while the input thread is actually reading data from the socket.
This causes the above deadlock.

The below patch quickly fabricated here makes the window of opportunity
for the situation to arise sufficiently small (its not a proper fix!).

Does anyone have a good idea of the causes of this problem and the
effects it has? I think some in-depth analysis would be in order to
solve the problem.

- Joris

--- libxcb-1.7/src/xcb_conn.c	2010-08-13 13:43:31.000000000 +0200
+++ libxcb-1.7.patched/src/xcb_conn.c	2010-12-01 14:26:10.000000000
+0100
@@ -48,6 +48,7 @@
     uint16_t length;
 } xcb_setup_generic_t;
 
+volatile int poll_spinlock = 0;
 static const int error_connection = 1;
 
 static int set_fd_flags(const int fd)
@@ -306,7 +307,7 @@
         ++c->out.writing;
     }
 #endif
-
+    poll_spinlock = 1;
     pthread_mutex_unlock(&c->iolock);
     do {
 #if USE_POLL
@@ -321,7 +322,7 @@
         ret = 0;
     }
     pthread_mutex_lock(&c->iolock);
-
+    poll_spinlock = 0;
     if(ret)
     {
 #if USE_POLL
--- libxcb-1.7/src/xcb_in.c	2010-08-13 13:43:31.000000000 +0200
+++ libxcb-1.7.patched/src/xcb_in.c	2010-12-01 14:26:22.000000000 +0100
@@ -45,6 +45,8 @@
 #define XCB_REPLY 1
 #define XCB_XGE_EVENT 35
 
+extern volatile int poll_spinlock;
+
 struct event_list {
     xcb_generic_event_t *event;
     struct event_list *next;
@@ -545,6 +547,9 @@
     xcb_generic_event_t *ret = 0;
     if(!c->has_error)
     {
+	while (poll_spinlock)
+		continue;
+
         pthread_mutex_lock(&c->iolock);
         /* FIXME: follow X meets Z architecture changes. */
         ret = get_event(c);



More information about the Xcb mailing list