Factor pthread_cond_wait(iolock) to _xcb_wait_io.
[free-sw/xcb/libxcb] / src / xcb_out.c
index edb0aa9..60226e5 100644 (file)
@@ -33,7 +33,7 @@
 #include "xcb.h"
 #include "xcbext.h"
 #include "xcbint.h"
-#include "extensions/bigreq.h"
+#include "bigreq.h"
 
 static int write_block(xcb_connection_t *c, struct iovec *vector, int count)
 {
@@ -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)
@@ -163,10 +187,10 @@ unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vect
         workaround = WORKAROUND_GLX_GET_FB_CONFIGS_BUG;
 
     /* get a sequence number and arrange for delivery. */
-    pthread_mutex_lock(&c->iolock);
+    _xcb_lock_io(c);
     /* wait for other writing threads to get out of my way. */
     while(c->out.writing)
-        pthread_cond_wait(&c->out.cond, &c->iolock);
+        _xcb_wait_io(c, &c->out.cond);
 
     request = ++c->out.request;
     /* send GetInputFocus (sync) when 64k-2 requests have been sent without
@@ -207,7 +231,7 @@ unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vect
         _xcb_conn_shutdown(c);
         request = 0;
     }
-    pthread_mutex_unlock(&c->iolock);
+    _xcb_unlock_io(c);
     return request;
 }
 
@@ -216,9 +240,9 @@ int xcb_flush(xcb_connection_t *c)
     int ret;
     if(c->has_error)
         return 0;
-    pthread_mutex_lock(&c->iolock);
+    _xcb_lock_io(c);
     ret = _xcb_out_flush_to(c, c->out.request);
-    pthread_mutex_unlock(&c->iolock);
+    _xcb_unlock_io(c);
     return ret;
 }
 
@@ -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;
 }
@@ -273,7 +297,7 @@ int _xcb_out_flush_to(xcb_connection_t *c, unsigned int request)
         return _xcb_out_send(c, &vec_ptr, &count);
     }
     while(c->out.writing)
-        pthread_cond_wait(&c->out.cond, &c->iolock);
+        _xcb_wait_io(c, &c->out.cond);
     assert(XCB_SEQUENCE_COMPARE(c->out.request_written, >=, request));
     return 1;
 }