summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGiovanni Mascellani <gmascellani@codeweavers.com>2022-02-04 10:49:25 +0100
committerMatt Turner <mattst88@gmail.com>2022-03-23 16:22:25 +0000
commit257927c51b08242aa5bf239346717fc817b2b286 (patch)
treebab8088fe1c42595dcdb97ac00dca9806ffc33cc /src
parent918063298cb893bee98040c9dca45ccdb2864773 (diff)
xcb_io: Allow jumps backwards when widening the request number.
Request numbers are not always seen in the numeric order by widen(), for example due to Mesa directly calling _XError(). When this happens, widen() adds 2^32 to the reported widened number, triggering failed assertions and bad behavior. With this commit, wrapping of the lower dword is detected in a more robust way, by requiring that a skip of at least 2^31 is seen. This fixes issue #152. Signed-off-by: Giovanni Mascellani <gmascellani@codeweavers.com>
Diffstat (limited to 'src')
-rw-r--r--src/xcb_io.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/src/xcb_io.c b/src/xcb_io.c
index dff441ff..d800a8e1 100644
--- a/src/xcb_io.c
+++ b/src/xcb_io.c
@@ -214,7 +214,12 @@ static int handle_error(Display *dpy, xError *err, Bool in_XReply)
static void widen(uint64_t *wide, unsigned int narrow)
{
uint64_t new = (*wide & ~((uint64_t)0xFFFFFFFFUL)) | narrow;
- *wide = new + (((uint64_t)(new < *wide)) << 32);
+ /* If just copying the upper dword of *wide makes the number
+ * go down by more than 2^31, then it means that the lower
+ * dword has wrapped (or we have skipped 2^31 requests, which
+ * is hopefully improbable), so we add a carry. */
+ uint64_t wraps = new + (1UL << 31) < *wide;
+ *wide = new + (wraps << 32);
}
/* Thread-safety rules: