From da4d56ef5a880eb24014a141e6e16668ab51f180 Mon Sep 17 00:00:00 2001 From: Jamey Sharp Date: Sun, 12 Nov 2006 15:30:10 -0800 Subject: [PATCH] Provide xcb_prefetch_maximum_request_length counterpart to xcb_get_maximum_request_length. --- src/xcb.h | 22 ++++++++++++++++++++-- src/xcb_ext.c | 2 +- src/xcb_out.c | 40 ++++++++++++++++++++++++++++++++-------- src/xcbint.h | 15 ++++++++++++++- 4 files changed, 67 insertions(+), 12 deletions(-) diff --git a/src/xcb.h b/src/xcb.h index 4c3e079..5a1c01a 100644 --- a/src/xcb.h +++ b/src/xcb.h @@ -183,8 +183,7 @@ typedef struct xcb_auth_info_t { int xcb_flush(xcb_connection_t *c); /** - * @brief Returns the maximum request length field from the connection - * setup data. + * @brief Returns the maximum request length that this server accepts. * @param c: The connection to the X server. * @return The maximum request length field. * @@ -200,6 +199,25 @@ int xcb_flush(xcb_connection_t *c); */ uint32_t xcb_get_maximum_request_length(xcb_connection_t *c); +/** + * @brief Prefetch the maximum request length without blocking. + * @param c: The connection to the X server. + * + * Without blocking, does as much work as possible toward computing + * the maximum request length accepted by the X server. + * + * Invoking this function may cause a call to xcb_big_requests_enable, + * but will not block waiting for the reply. + * xcb_get_maximum_request_length will return the prefetched data + * after possibly blocking while the reply is retrieved. + * + * Note that in order for this function to be fully non-blocking, the + * application must previously have called + * xcb_prefetch_extension_data(c, &xcb_big_requests_id) and the reply + * must have already arrived. + */ +void xcb_prefetch_maximum_request_length(xcb_connection_t *c); + /* xcb_in.c */ diff --git a/src/xcb_ext.c b/src/xcb_ext.c index 9655dd8..12cb164 100644 --- a/src/xcb_ext.c +++ b/src/xcb_ext.c @@ -33,7 +33,7 @@ #include "xcbint.h" typedef struct lazyreply { - enum { LAZY_NONE = 0, LAZY_COOKIE, LAZY_FORCED } tag; + enum lazy_reply_tag tag; union { xcb_query_extension_cookie_t cookie; xcb_query_extension_reply_t *reply; diff --git a/src/xcb_out.c b/src/xcb_out.c index 74787e3..caf8ef5 100644 --- a/src/xcb_out.c +++ b/src/xcb_out.c @@ -57,25 +57,49 @@ static int write_block(xcb_connection_t *c, struct iovec *vector, int count) /* Public interface */ -uint32_t xcb_get_maximum_request_length(xcb_connection_t *c) +void xcb_prefetch_maximum_request_length(xcb_connection_t *c) { if(c->has_error) - return 0; + return; pthread_mutex_lock(&c->out.reqlenlock); - if(!c->out.maximum_request_length) + if(c->out.maximum_request_length_tag == LAZY_NONE) { const xcb_query_extension_reply_t *ext; - c->out.maximum_request_length = c->setup->maximum_request_length; ext = xcb_get_extension_data(c, &xcb_big_requests_id); if(ext && ext->present) { - xcb_big_requests_enable_reply_t *r = xcb_big_requests_enable_reply(c, xcb_big_requests_enable(c), 0); - c->out.maximum_request_length = r->maximum_request_length; + c->out.maximum_request_length_tag = LAZY_COOKIE; + c->out.maximum_request_length.cookie = xcb_big_requests_enable(c); + } + else + { + c->out.maximum_request_length_tag = LAZY_FORCED; + c->out.maximum_request_length.value = c->setup->maximum_request_length; + } + } + pthread_mutex_unlock(&c->out.reqlenlock); +} + +uint32_t xcb_get_maximum_request_length(xcb_connection_t *c) +{ + if(c->has_error) + return 0; + xcb_prefetch_maximum_request_length(c); + pthread_mutex_lock(&c->out.reqlenlock); + if(c->out.maximum_request_length_tag == LAZY_COOKIE) + { + xcb_big_requests_enable_reply_t *r = xcb_big_requests_enable_reply(c, c->out.maximum_request_length.cookie, 0); + c->out.maximum_request_length_tag = LAZY_FORCED; + if(r) + { + c->out.maximum_request_length.value = r->maximum_request_length; free(r); } + else + c->out.maximum_request_length.value = c->setup->maximum_request_length; } pthread_mutex_unlock(&c->out.reqlenlock); - return c->out.maximum_request_length; + return c->out.maximum_request_length.value; } unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vector, const xcb_protocol_request_t *req) @@ -237,7 +261,7 @@ int _xcb_out_init(_xcb_out *out) if(pthread_mutex_init(&out->reqlenlock, 0)) return 0; - out->maximum_request_length = 0; + out->maximum_request_length_tag = LAZY_NONE; return 1; } diff --git a/src/xcbint.h b/src/xcbint.h index d81e787..93bc89b 100644 --- a/src/xcbint.h +++ b/src/xcbint.h @@ -28,6 +28,8 @@ #ifndef __XCBINT_H #define __XCBINT_H +#include "bigreq.h" + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -41,6 +43,13 @@ enum workarounds { WORKAROUND_GLX_GET_FB_CONFIGS_BUG }; +enum lazy_reply_tag +{ + LAZY_NONE = 0, + LAZY_COOKIE, + LAZY_FORCED +}; + #define XCB_PAD(i) (-(i) & 3) #define XCB_SEQUENCE_COMPARE(a,op,b) ((int) ((a) - (b)) op 0) @@ -70,7 +79,11 @@ typedef struct _xcb_out { unsigned int request_written; pthread_mutex_t reqlenlock; - uint32_t maximum_request_length; + enum lazy_reply_tag maximum_request_length_tag; + union { + xcb_big_requests_enable_cookie_t cookie; + uint32_t value; + } maximum_request_length; } _xcb_out; int _xcb_out_init(_xcb_out *out); -- 2.34.1