diff options
author | Chris Robinson <[email protected]> | 2016-02-07 17:47:52 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2016-02-07 17:47:52 -0800 |
commit | 000ced37951795d4ded85b37a5337dbfdee90be1 (patch) | |
tree | 47e6e8d08b408d872a711d3768aa726ef2722c6c /common | |
parent | f4fa41487c18ece49fddb512e3d9253e6eb1e92b (diff) |
Avoid underflow in alcnd_timedwait if the time point is already passed
Diffstat (limited to 'common')
-rw-r--r-- | common/threads.c | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/common/threads.c b/common/threads.c index 6272dd9f..5a177a2c 100644 --- a/common/threads.c +++ b/common/threads.c @@ -264,10 +264,19 @@ int alcnd_timedwait(alcnd_t *cond, almtx_t *mtx, const struct timespec *time_poi if(altimespec_get(&curtime, AL_TIME_UTC) != AL_TIME_UTC) return althrd_error; - sleeptime = (time_point->tv_nsec - curtime.tv_nsec + 999999)/1000000; - sleeptime += (time_point->tv_sec - curtime.tv_sec)*1000; - if(SleepConditionVariableCS(cond, mtx, sleeptime) != 0) - return althrd_success; + if(curtime.tv_sec > time_point->tv_sec || (curtime.tv_sec == time_point->tv_sec && + curtime.tv_nsec >= time_point->tv_nsec)) + { + if(SleepConditionVariableCS(cond, mtx, 0) != 0) + return althrd_success; + } + else + { + sleeptime = (time_point->tv_nsec - curtime.tv_nsec + 999999)/1000000; + sleeptime += (time_point->tv_sec - curtime.tv_sec)*1000; + if(SleepConditionVariableCS(cond, mtx, sleeptime) != 0) + return althrd_success; + } return (GetLastError()==ERROR_TIMEOUT) ? althrd_timedout : althrd_error; } @@ -364,8 +373,15 @@ int alcnd_timedwait(alcnd_t *cond, almtx_t *mtx, const struct timespec *time_poi if(altimespec_get(&curtime, AL_TIME_UTC) != AL_TIME_UTC) return althrd_error; - sleeptime = (time_point->tv_nsec - curtime.tv_nsec + 999999)/1000000; - sleeptime += (time_point->tv_sec - curtime.tv_sec)*1000; + + if(curtime.tv_sec > time_point->tv_sec || (curtime.tv_sec == time_point->tv_sec && + curtime.tv_nsec >= time_point->tv_nsec)) + sleeptime = 0; + else + { + sleeptime = (time_point->tv_nsec - curtime.tv_nsec + 999999)/1000000; + sleeptime += (time_point->tv_sec - curtime.tv_sec)*1000; + } IncrementRef(&icond->wait_count); LeaveCriticalSection(mtx); |