Merge branch 'try-flush' into 'master'

Draft: Introduce xcb_try_flush()

See merge request xorg/lib/libxcb!83
This commit is contained in:
Uli Schlachter 2026-03-22 06:31:54 +00:00
commit 951ea334b1
4 changed files with 72 additions and 0 deletions

View file

@ -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.

View file

@ -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;

View file

@ -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)

View file

@ -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 */