aboutsummaryrefslogtreecommitdiffstats
path: root/common/threads.c
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2016-02-07 17:47:52 -0800
committerChris Robinson <[email protected]>2016-02-07 17:47:52 -0800
commit000ced37951795d4ded85b37a5337dbfdee90be1 (patch)
tree47e6e8d08b408d872a711d3768aa726ef2722c6c /common/threads.c
parentf4fa41487c18ece49fddb512e3d9253e6eb1e92b (diff)
Avoid underflow in alcnd_timedwait if the time point is already passed
Diffstat (limited to 'common/threads.c')
-rw-r--r--common/threads.c28
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);