Commit a29fbc26 authored by Jamey Sharp's avatar Jamey Sharp
Browse files

Don't hold the xlib-xcb lock while sleeping: that allows deadlock.



With this patch, `ico -threads 2` runs without deadlock.

Many thanks to Christoph Pfister <christophpfister@gmail.com> for
pointing out the problem, providing detailed analyses, explaining it to
me repeatedly until I understood what was going on, and proposing and
reviewing possible solutions.
Signed-off-by: Jamey Sharp's avatarJamey Sharp <jamey@minilop.net>
Acked-by: default avatarChristoph Pfister <christophpfister@gmail.com>
parent f6b75d60
......@@ -290,12 +290,25 @@ void _xcb_unlock_io(xcb_connection_t *c)
void _xcb_wait_io(xcb_connection_t *c, pthread_cond_t *cond)
{
int xlib_locked = c->xlib.lock;
if(xlib_locked)
{
c->xlib.lock = 0;
pthread_cond_broadcast(&c->xlib.cond);
}
pthread_cond_wait(cond, &c->iolock);
if(xlib_locked)
{
while(c->xlib.lock)
pthread_cond_wait(&c->xlib.cond, &c->iolock);
c->xlib.lock = 1;
c->xlib.thread = pthread_self();
}
}
int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vector, int *count)
{
int ret;
int ret, xlib_locked;
fd_set rfds, wfds;
/* If the thing I should be doing is already being done, wait for it. */
......@@ -316,6 +329,12 @@ int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vec
++c->out.writing;
}
xlib_locked = c->xlib.lock;
if(xlib_locked)
{
c->xlib.lock = 0;
pthread_cond_broadcast(&c->xlib.cond);
}
_xcb_unlock_io(c);
do {
ret = select(c->fd + 1, &rfds, &wfds, 0, 0);
......@@ -326,6 +345,11 @@ int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vec
ret = 0;
}
_xcb_lock_io(c);
if(xlib_locked)
{
c->xlib.lock = 1;
c->xlib.thread = pthread_self();
}
if(ret)
{
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment