Fix hang in xcb_request_check()
This fixes https://gitlab.freedesktop.org/xorg/lib/libxcb/-/issues/53 The issue was that libxcb expected to get a reply based on the request_expected variable, but a reply would never arrive because the request was never actually written. To resolve this, a separate request_expected_written variable is added.
This commit is contained in:
parent
dc28118747
commit
233d7b7f1f
13
src/xcb_in.c
13
src/xcb_in.c
|
@ -736,11 +736,16 @@ xcb_generic_error_t *xcb_request_check(xcb_connection_t *c, xcb_void_cookie_t co
|
||||||
return 0;
|
return 0;
|
||||||
pthread_mutex_lock(&c->iolock);
|
pthread_mutex_lock(&c->iolock);
|
||||||
request = widen(c, cookie.sequence);
|
request = widen(c, cookie.sequence);
|
||||||
if(XCB_SEQUENCE_COMPARE(request, >=, c->in.request_expected)
|
if (XCB_SEQUENCE_COMPARE(request, >, c->in.request_completed))
|
||||||
&& XCB_SEQUENCE_COMPARE(request, >, c->in.request_completed))
|
|
||||||
{
|
{
|
||||||
_xcb_out_send_sync(c);
|
if(XCB_SEQUENCE_COMPARE(request, >=, c->in.request_expected))
|
||||||
_xcb_out_flush_to(c, c->out.request);
|
{
|
||||||
|
_xcb_out_send_sync(c);
|
||||||
|
}
|
||||||
|
if (XCB_SEQUENCE_COMPARE(request, >=, c->out.request_expected_written))
|
||||||
|
{
|
||||||
|
_xcb_out_flush_to(c, c->out.request);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
reply = wait_for_reply(c, request, &ret);
|
reply = wait_for_reply(c, request, &ret);
|
||||||
assert(!reply);
|
assert(!reply);
|
||||||
|
|
|
@ -447,6 +447,7 @@ int _xcb_out_init(_xcb_out *out)
|
||||||
|
|
||||||
out->request = 0;
|
out->request = 0;
|
||||||
out->request_written = 0;
|
out->request_written = 0;
|
||||||
|
out->request_expected_written = 0;
|
||||||
|
|
||||||
if(pthread_mutex_init(&out->reqlenlock, 0))
|
if(pthread_mutex_init(&out->reqlenlock, 0))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -467,6 +468,7 @@ int _xcb_out_send(xcb_connection_t *c, struct iovec *vector, int count)
|
||||||
while(ret && count)
|
while(ret && count)
|
||||||
ret = _xcb_conn_wait(c, &c->out.cond, &vector, &count);
|
ret = _xcb_conn_wait(c, &c->out.cond, &vector, &count);
|
||||||
c->out.request_written = c->out.request;
|
c->out.request_written = c->out.request;
|
||||||
|
c->out.request_expected_written = c->in.request_expected;
|
||||||
pthread_cond_broadcast(&c->out.cond);
|
pthread_cond_broadcast(&c->out.cond);
|
||||||
_xcb_in_wake_up_next_reader(c);
|
_xcb_in_wake_up_next_reader(c);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -113,6 +113,7 @@ typedef struct _xcb_out {
|
||||||
|
|
||||||
uint64_t request;
|
uint64_t request;
|
||||||
uint64_t request_written;
|
uint64_t request_written;
|
||||||
|
uint64_t request_expected_written;
|
||||||
uint64_t total_written;
|
uint64_t total_written;
|
||||||
|
|
||||||
pthread_mutex_t reqlenlock;
|
pthread_mutex_t reqlenlock;
|
||||||
|
|
Loading…
Reference in New Issue