(timeout in ms vs. XSyncValueSubtract) Frozen client, found cause, need advise for fix

Daniel Martin consume.noise at gmail.com
Mon Feb 20 09:55:02 UTC 2017


Hi everyone,

I've got a Qt5 client, which receives mouse input only and freezes
soon and often. It gets stuck waiting for a reply from the server.
Pressing a none-modifier key releases the lock and the client
continues as normal until the next freeze.

I've traced the bug down to a regression implicitly introduced by:
    e6636b4 os: Compute timeout in milliseconds instead of struct timeval
Which states "simplifies the code without affecting functionality at all". ;-)

What happens is:
- ServertimeBlockHandler() forwards a _big_ unsigned timeout to
AdjustWaitForDelay()
- AdjustWaitForDelay() takes this _big_ unsigned as int and it becomes
a negative value
- the negative value ends up as timeout in ospoll_wait() as parameter
to epoll_wait()
> epoll_wait() blocks due to the negative timeout

XSyncValueSubtract() doesn't handle unsigned wraps. That's why we get
a big unsigned from ServertimeBlockHandler(). Just imagine two
XSyncValues:
    a = {.hi=1, .lo=1} and b = {.hi=0, lo=.2}.
The result of XSyncValueSubtract(a - b) is
    presult = {.hi=0, .lo=4294967295},
where I would expect
   presult = {.hi=0, .lo=9}.

If .lo=4294967295 is wrong and .lo=9 is what we want, could anyone
provide a fix, please? I'm to dumb for the (binary?) arithmetic atm.
(And if it is wrong, did I just uncovered an ancient bug?)

To paper over the (mis)behaviour of XSyncValueSubtract() I would
suggest to make sure that AdjustWaitForDelay() doesn't return negative
values. We can't check for negatives in ospoll_wait() as the input
thread calls it with -1.

Other thoughts: Why does the cursor move, but neither the movement or
clicks, nor pressing a modifier unlock the client?


Cheers,
    Daniel Martin


More information about the xorg-devel mailing list