Provide xcb_prefetch_maximum_request_length counterpart to xcb_get_maximum_request_le...
authorJamey Sharp <jamey@minilop.net>
Sun, 12 Nov 2006 23:30:10 +0000 (15:30 -0800)
committerJamey Sharp <jamey@minilop.net>
Sun, 19 Nov 2006 06:38:42 +0000 (22:38 -0800)
src/xcb.h
src/xcb_ext.c
src/xcb_out.c
src/xcbint.h

index 4c3e079..5a1c01a 100644 (file)
--- 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 */
 
index 9655dd8..12cb164 100644 (file)
@@ -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;
index 74787e3..caf8ef5 100644 (file)
@@ -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;
 }
index d81e787..93bc89b 100644 (file)
@@ -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);