ole32: fix wrong timeout check

Alexander Dorofeyev alexd4 at inbox.lv
Sat Dec 22 16:37:32 CST 2007

Yeah these calculations are a headache. I could probably write

now < start_time || now >= start_time + dwTimeout

to at least avoid a "hang" if GetTickCount counter overflows. This won't solve 
not waiting the required time if, say, start_time + dwTimeout overflows, and 
that can also be a problem (for example, I found this bug by bisecting a 
regression in an installer that happened because the function didn't properly 
wait). To be really purist, we would probably need a macro or a function with 
branching that correctly handles all possible overflow situations and tells if 
the required interval elapsed between "tick" values A and B. I wonder if a patch 
like that would be accepted, though, and also in what file this macro/function 
could be implemented?

This seems to be pretty widespread, too, one of CoWaitForMultipleHandles callers 
- RPC_GetLocalClassObject - now also has a similar timeout check.

Dan Kegel wrote:
>> -        if ((dwTimeout != INFINITE) && (start_time + dwTimeout >= now))
>> +        if ((dwTimeout != INFINITE) && (now >= start_time + dwTimeout))
>>From time immemorial, it has been drummed into me
> that one should always handle wraparound when
> checking timers.  So something like
>     DWORD delta = now - start_time;
>     if (dwTimeout != INFINITE) && (delta < 0x80000000UL) && (delta > dwTimeout))
> might be more correct... I used to always use
> a signed variable for this, but C compilers
> now treat overflow of signed variables as
> a conceptual error, so the subtraction has to be unsigned,
> There's probably a cleaner way to code this,
> but doing the subtraction to get the delta time,
> and then comparing against the maximum desired
> delta time, is the way to avoid trouble at rollover.
> - Dan

More information about the wine-devel mailing list