diff --git a/src/libCom/osi/os/WIN32/osdEvent.c b/src/libCom/osi/os/WIN32/osdEvent.c index fb67d6c79..e39608255 100644 --- a/src/libCom/osi/os/WIN32/osdEvent.c +++ b/src/libCom/osi/os/WIN32/osdEvent.c @@ -92,17 +92,27 @@ epicsShareFunc epicsEventStatus epicsEventWait ( epicsEventId pSem ) epicsShareFunc epicsEventStatus epicsEventWaitWithTimeout ( epicsEventId pSem, double timeOut ) { - static const unsigned nSec100PerSec = 10000000u; + /* waitable timers use 100 nanosecond intervals, like FILETIME */ + static const unsigned ivalPerSec = 10000000u; /* number of 100ns intervals per second */ + static const unsigned mSecPerSec = 1000u; /* milliseconds per second */ HANDLE handles[2]; DWORD status; LARGE_INTEGER tmo; HANDLE timer; + LONGLONG nIvals; /* number of intervals */ if ( timeOut <= 0.0 ) { tmo.QuadPart = 0u; } + else if ( timeOut >= INFINITE / mSecPerSec ) { + /* we need to apply a maximum wait time to stop an overflow. We choose (INFINITE - 1) milliseconds, + to be compatible with previous WaitForSingleObject() implementation */ + nIvals = (LONGLONG)(INFINITE - 1) * (ivalPerSec / mSecPerSec); + tmo.QuadPart = -nIvals; /* negative value means a relative time offset for timer */ + } else { - tmo.QuadPart = -((LONGLONG)(timeOut * nSec100PerSec + 0.5)); + nIvals = (LONGLONG)(timeOut * ivalPerSec + 0.999999); + tmo.QuadPart = -nIvals; } if (tmo.QuadPart < 0) { diff --git a/src/libCom/osi/os/WIN32/osdThread.c b/src/libCom/osi/os/WIN32/osdThread.c index 0057ee953..092432e71 100644 --- a/src/libCom/osi/os/WIN32/osdThread.c +++ b/src/libCom/osi/os/WIN32/osdThread.c @@ -807,15 +807,25 @@ HANDLE osdThreadGetTimer() */ epicsShareFunc void epicsShareAPI epicsThreadSleep ( double seconds ) { - static const unsigned nSec100PerSec = 10000000u; + /* waitable timers use 100 nanosecond intervals, like FILETIME */ + static const unsigned ivalPerSec = 10000000u; /* number of 100ns intervals per second */ + static const unsigned mSecPerSec = 1000u; /* milliseconds per second */ LARGE_INTEGER tmo; HANDLE timer; + LONGLONG nIvals; /* number of intervals */ if ( seconds <= 0.0 ) { tmo.QuadPart = 0u; } + else if ( seconds >= INFINITE / mSecPerSec ) { + /* we need to apply a maximum wait time to stop an overflow. We choose (INFINITE - 1) milliseconds, + to be compatible with previous WaitForSingleObject() implementation */ + nIvals = (LONGLONG)(INFINITE - 1) * (ivalPerSec / mSecPerSec); + tmo.QuadPart = -nIvals; /* negative value means a relative time offset for timer */ + } else { - tmo.QuadPart = -((LONGLONG)(seconds * nSec100PerSec + 0.5)); + nIvals = (LONGLONG)(seconds * ivalPerSec + 0.999999); + tmo.QuadPart = -nIvals; } if (tmo.QuadPart == 0) {