[Xcb-commit] libxcb: src

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Oct 1 05:34:54 UTC 2021


 src/xcb_in.c  |   13 +++++++++----
 src/xcb_out.c |    2 ++
 src/xcbint.h  |    1 +
 3 files changed, 12 insertions(+), 4 deletions(-)

New commits:
commit 233d7b7f1f03ef18bf3955eb1f20421e745d22f0
Author: Thomas Anderson <thomasanderson at google.com>
Date:   Wed Dec 2 00:25:42 2020 +0000

    Fix hang in xcb_request_check()
    
    This fixes https://gitlab.freedesktop.org/xorg/lib/libxcb/-/issues/53
    
    The issue was that libxcb expected to get a reply based on the request_expected
    variable, but a reply would never arrive because the request was never actually
    written.  To resolve this, a separate request_expected_written variable is
    added.

diff --git a/src/xcb_in.c b/src/xcb_in.c
index 7d02e9b..4862464 100644
--- a/src/xcb_in.c
+++ b/src/xcb_in.c
@@ -736,11 +736,16 @@ xcb_generic_error_t *xcb_request_check(xcb_connection_t *c, xcb_void_cookie_t co
         return 0;
     pthread_mutex_lock(&c->iolock);
     request = widen(c, cookie.sequence);
-    if(XCB_SEQUENCE_COMPARE(request, >=, c->in.request_expected)
-       && XCB_SEQUENCE_COMPARE(request, >, c->in.request_completed))
+    if (XCB_SEQUENCE_COMPARE(request, >, c->in.request_completed))
     {
-        _xcb_out_send_sync(c);
-        _xcb_out_flush_to(c, c->out.request);
+        if(XCB_SEQUENCE_COMPARE(request, >=, c->in.request_expected))
+        {
+            _xcb_out_send_sync(c);
+        }
+        if (XCB_SEQUENCE_COMPARE(request, >=, c->out.request_expected_written))
+        {
+            _xcb_out_flush_to(c, c->out.request);
+        }
     }
     reply = wait_for_reply(c, request, &ret);
     assert(!reply);
diff --git a/src/xcb_out.c b/src/xcb_out.c
index df94867..8ffc03f 100644
--- a/src/xcb_out.c
+++ b/src/xcb_out.c
@@ -447,6 +447,7 @@ int _xcb_out_init(_xcb_out *out)
 
     out->request = 0;
     out->request_written = 0;
+    out->request_expected_written = 0;
 
     if(pthread_mutex_init(&out->reqlenlock, 0))
         return 0;
@@ -467,6 +468,7 @@ int _xcb_out_send(xcb_connection_t *c, struct iovec *vector, int count)
     while(ret && count)
         ret = _xcb_conn_wait(c, &c->out.cond, &vector, &count);
     c->out.request_written = c->out.request;
+    c->out.request_expected_written = c->in.request_expected;
     pthread_cond_broadcast(&c->out.cond);
     _xcb_in_wake_up_next_reader(c);
     return ret;
diff --git a/src/xcbint.h b/src/xcbint.h
index 6a070f8..235c848 100644
--- a/src/xcbint.h
+++ b/src/xcbint.h
@@ -113,6 +113,7 @@ typedef struct _xcb_out {
 
     uint64_t request;
     uint64_t request_written;
+    uint64_t request_expected_written;
     uint64_t total_written;
 
     pthread_mutex_t reqlenlock;


More information about the xcb-commit mailing list