xcb_request_check: Hold the I/O lock while deciding to sync.
Signed-off-by: Jamey Sharp <jamey@minilop.net>
This commit is contained in:
parent
ee1bc1d28a
commit
3a74b5e7a1
42
src/xcb_in.c
42
src/xcb_in.c
|
@ -356,20 +356,10 @@ static int poll_for_reply(xcb_connection_t *c, unsigned int request, void **repl
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Public interface */
|
static void *wait_for_reply(xcb_connection_t *c, unsigned int request, xcb_generic_error_t **e)
|
||||||
|
|
||||||
void *xcb_wait_for_reply(xcb_connection_t *c, unsigned int request, xcb_generic_error_t **e)
|
|
||||||
{
|
{
|
||||||
uint64_t widened_request;
|
|
||||||
void *ret = 0;
|
void *ret = 0;
|
||||||
if(e)
|
uint64_t widened_request = (c->out.request & UINT64_C(0xffffffff00000000)) | request;
|
||||||
*e = 0;
|
|
||||||
if(c->has_error)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
pthread_mutex_lock(&c->iolock);
|
|
||||||
|
|
||||||
widened_request = (c->out.request & UINT64_C(0xffffffff00000000)) | request;
|
|
||||||
if(widened_request > c->out.request)
|
if(widened_request > c->out.request)
|
||||||
widened_request -= UINT64_C(1) << 32;
|
widened_request -= UINT64_C(1) << 32;
|
||||||
|
|
||||||
|
@ -411,6 +401,21 @@ void *xcb_wait_for_reply(xcb_connection_t *c, unsigned int request, xcb_generic_
|
||||||
}
|
}
|
||||||
|
|
||||||
_xcb_in_wake_up_next_reader(c);
|
_xcb_in_wake_up_next_reader(c);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Public interface */
|
||||||
|
|
||||||
|
void *xcb_wait_for_reply(xcb_connection_t *c, unsigned int request, xcb_generic_error_t **e)
|
||||||
|
{
|
||||||
|
void *ret;
|
||||||
|
if(e)
|
||||||
|
*e = 0;
|
||||||
|
if(c->has_error)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&c->iolock);
|
||||||
|
ret = wait_for_reply(c, request, e);
|
||||||
pthread_mutex_unlock(&c->iolock);
|
pthread_mutex_unlock(&c->iolock);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -575,21 +580,20 @@ xcb_generic_event_t *xcb_poll_for_event(xcb_connection_t *c)
|
||||||
|
|
||||||
xcb_generic_error_t *xcb_request_check(xcb_connection_t *c, xcb_void_cookie_t cookie)
|
xcb_generic_error_t *xcb_request_check(xcb_connection_t *c, xcb_void_cookie_t cookie)
|
||||||
{
|
{
|
||||||
/* FIXME: this could hold the lock to avoid syncing unnecessarily, but
|
xcb_generic_error_t *ret = 0;
|
||||||
* that would require factoring the locking out of xcb_get_input_focus,
|
|
||||||
* xcb_get_input_focus_reply, and xcb_wait_for_reply. */
|
|
||||||
xcb_generic_error_t *ret;
|
|
||||||
void *reply;
|
void *reply;
|
||||||
if(c->has_error)
|
if(c->has_error)
|
||||||
return 0;
|
return 0;
|
||||||
|
pthread_mutex_lock(&c->iolock);
|
||||||
if(XCB_SEQUENCE_COMPARE_32(cookie.sequence,>=,c->in.request_expected)
|
if(XCB_SEQUENCE_COMPARE_32(cookie.sequence,>=,c->in.request_expected)
|
||||||
&& XCB_SEQUENCE_COMPARE_32(cookie.sequence,>,c->in.request_completed))
|
&& XCB_SEQUENCE_COMPARE_32(cookie.sequence,>,c->in.request_completed))
|
||||||
{
|
{
|
||||||
free(xcb_get_input_focus_reply(c, xcb_get_input_focus(c), &ret));
|
_xcb_out_send_sync(c);
|
||||||
assert(!ret);
|
_xcb_out_flush_to(c, c->out.request);
|
||||||
}
|
}
|
||||||
reply = xcb_wait_for_reply(c, cookie.sequence, &ret);
|
reply = wait_for_reply(c, cookie.sequence, &ret);
|
||||||
assert(!reply);
|
assert(!reply);
|
||||||
|
pthread_mutex_unlock(&c->iolock);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -343,6 +343,15 @@ int _xcb_out_send(xcb_connection_t *c, struct iovec *vector, int count)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _xcb_out_send_sync(xcb_connection_t *c)
|
||||||
|
{
|
||||||
|
/* wait for other writing threads to get out of my way. */
|
||||||
|
while(c->out.writing)
|
||||||
|
pthread_cond_wait(&c->out.cond, &c->iolock);
|
||||||
|
get_socket_back(c);
|
||||||
|
send_sync(c);
|
||||||
|
}
|
||||||
|
|
||||||
int _xcb_out_flush_to(xcb_connection_t *c, uint64_t request)
|
int _xcb_out_flush_to(xcb_connection_t *c, uint64_t request)
|
||||||
{
|
{
|
||||||
assert(XCB_SEQUENCE_COMPARE(request, <=, c->out.request));
|
assert(XCB_SEQUENCE_COMPARE(request, <=, c->out.request));
|
||||||
|
|
|
@ -107,6 +107,7 @@ int _xcb_out_init(_xcb_out *out);
|
||||||
void _xcb_out_destroy(_xcb_out *out);
|
void _xcb_out_destroy(_xcb_out *out);
|
||||||
|
|
||||||
int _xcb_out_send(xcb_connection_t *c, struct iovec *vector, int count);
|
int _xcb_out_send(xcb_connection_t *c, struct iovec *vector, int count);
|
||||||
|
void _xcb_out_send_sync(xcb_connection_t *c);
|
||||||
int _xcb_out_flush_to(xcb_connection_t *c, uint64_t request);
|
int _xcb_out_flush_to(xcb_connection_t *c, uint64_t request);
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue