diff options
author | Giovanni Mascellani <gmascellani@codeweavers.com> | 2022-02-04 10:49:25 +0100 |
---|---|---|
committer | Matt Turner <mattst88@gmail.com> | 2022-03-23 16:22:25 +0000 |
commit | 257927c51b08242aa5bf239346717fc817b2b286 (patch) | |
tree | bab8088fe1c42595dcdb97ac00dca9806ffc33cc /src | |
parent | 918063298cb893bee98040c9dca45ccdb2864773 (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.c | 7 |
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: |