mirror of
https://gitlab.freedesktop.org/xorg/lib/libxcb.git
synced 2026-04-23 21:30:38 +02:00
Merge branch 'try-flush' into 'master'
Draft: Introduce xcb_try_flush() See merge request xorg/lib/libxcb!83
This commit is contained in:
commit
951ea334b1
4 changed files with 72 additions and 0 deletions
10
src/xcb.h
10
src/xcb.h
|
|
@ -269,6 +269,16 @@ typedef struct xcb_auth_info_t {
|
|||
*/
|
||||
int xcb_flush(xcb_connection_t *c);
|
||||
|
||||
/**
|
||||
* @brief Try to write any buffered output to the server.
|
||||
* @param c The connection to the X server.
|
||||
* @return > @c 0 on success, <= @c 0 otherwise.
|
||||
*
|
||||
* Writes any buffered output to the server. Does not block until the
|
||||
* write is complete, but instead returns immediately with a success.
|
||||
*/
|
||||
int xcb_try_flush(xcb_connection_t *c);
|
||||
|
||||
/**
|
||||
* @brief Returns the maximum request length that this server accepts.
|
||||
* @param c The connection to the X server.
|
||||
|
|
|
|||
|
|
@ -560,6 +560,55 @@ int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vec
|
|||
return ret;
|
||||
}
|
||||
|
||||
int _xcb_conn_try_flush(xcb_connection_t *c)
|
||||
{
|
||||
int ret;
|
||||
int count;
|
||||
int original_out_queue_len;
|
||||
struct iovec vec;
|
||||
struct iovec *vec_ptr;
|
||||
|
||||
original_out_queue_len = c->out.queue_len;
|
||||
if (c->out.writing || original_out_queue_len == 0) {
|
||||
/* If another thread is already writing, we would have to block, waiting
|
||||
* for it. If there is nothing to write, there is nothing to write. So
|
||||
* just return success.
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
c->out.queue_len = 0;
|
||||
|
||||
count = 1;
|
||||
vec.iov_base = c->out.queue;
|
||||
vec.iov_len = original_out_queue_len;
|
||||
vec_ptr = &vec;
|
||||
ret = write_vec(c, &vec_ptr, &count);
|
||||
|
||||
/* Remove all written data from the queue */
|
||||
if (vec.iov_len == 0) {
|
||||
/* Everything was written */
|
||||
c->out.queue_len = 0;
|
||||
|
||||
/* Update state on which requests are already flushed */
|
||||
c->out.request_written = c->out.request;
|
||||
c->out.request_expected_written = c->in.request_expected;
|
||||
} else {
|
||||
/* Move the remaining data to the front of the queue */
|
||||
int remaining = vec.iov_len;
|
||||
int written = original_out_queue_len - remaining;
|
||||
memmove(&c->out.queue[0], &c->out.queue[written], remaining);
|
||||
c->out.queue_len = remaining;
|
||||
}
|
||||
|
||||
/*
|
||||
* No need to wake up readers since we did not read.
|
||||
* No need to wake up sleeping writers since there can be none.
|
||||
*/
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint64_t xcb_total_read(xcb_connection_t *c)
|
||||
{
|
||||
uint64_t n;
|
||||
|
|
|
|||
|
|
@ -429,6 +429,17 @@ int xcb_flush(xcb_connection_t *c)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int xcb_try_flush(xcb_connection_t *c)
|
||||
{
|
||||
int ret;
|
||||
if(c->has_error)
|
||||
return 0;
|
||||
pthread_mutex_lock(&c->iolock);
|
||||
ret = _xcb_conn_try_flush(c);
|
||||
pthread_mutex_unlock(&c->iolock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Private interface */
|
||||
|
||||
int _xcb_out_init(_xcb_out *out)
|
||||
|
|
|
|||
|
|
@ -228,6 +228,8 @@ xcb_connection_t *_xcb_conn_ret_error(int err);
|
|||
|
||||
int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vector, int *count);
|
||||
|
||||
int _xcb_conn_try_flush(xcb_connection_t *c);
|
||||
|
||||
|
||||
/* xcb_auth.c */
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue