fixed S_condition_wait Y2038 bug; rounding ns to ms on Windows - now using 64-bit arithmetic for seconds in S_condition_wait to prevent a potential 2038 bug, at least on platforms where time_t is 64 bits. also now rounding rather than truncating nanoseconds in the coversion to milliseconds on Windows. thread.c

This commit is contained in:
dyb 2020-08-25 22:34:34 -07:00 committed by Matthew Flatt
parent 13ee990165
commit aa2208eb04
2 changed files with 12 additions and 7 deletions

View File

@ -2135,3 +2135,8 @@
- added textual-output-port checks for record-writer write argument
print.ss,
record.ms, root-experr*
- now using 64-bit arithmetic for seconds in S_condition_wait to
prevent a potential 2038 bug, at least on platforms where time_t
is 64 bits. also now rounding rather than truncating nanoseconds
in the coversion to milliseconds on Windows.
thread.c

View File

@ -456,11 +456,11 @@ void S_condition_free(c) s_thread_cond_t *c; {
#ifdef FEATURE_WINDOWS
static inline int s_thread_cond_timedwait(s_thread_cond_t *cond, s_thread_mutex_t *mutex, int typeno, long sec, long nsec) {
static inline int s_thread_cond_timedwait(s_thread_cond_t *cond, s_thread_mutex_t *mutex, int typeno, I64 sec, long nsec) {
if (typeno == time_utc) {
struct timespec now;
S_gettime(time_utc, &now);
sec -= (long)now.tv_sec;
sec -= now.tv_sec;
nsec -= now.tv_nsec;
if (nsec < 0) {
sec -= 1;
@ -471,7 +471,7 @@ static inline int s_thread_cond_timedwait(s_thread_cond_t *cond, s_thread_mutex_
sec = 0;
nsec = 0;
}
if (SleepConditionVariableCS(cond, mutex, sec*1000 + nsec/1000000)) {
if (SleepConditionVariableCS(cond, mutex, (DWORD)(sec*1000 + (nsec+500000)/1000000))) {
return 0;
} else if (GetLastError() == ERROR_TIMEOUT) {
return ETIMEDOUT;
@ -482,12 +482,12 @@ static inline int s_thread_cond_timedwait(s_thread_cond_t *cond, s_thread_mutex_
#else /* FEATURE_WINDOWS */
static inline int s_thread_cond_timedwait(s_thread_cond_t *cond, s_thread_mutex_t *mutex, int typeno, long sec, long nsec) {
static inline int s_thread_cond_timedwait(s_thread_cond_t *cond, s_thread_mutex_t *mutex, int typeno, I64 sec, long nsec) {
struct timespec t;
if (typeno == time_duration) {
struct timespec now;
S_gettime(time_utc, &now);
t.tv_sec = now.tv_sec + sec;
t.tv_sec = (time_t)(now.tv_sec + sec);
t.tv_nsec = now.tv_nsec + nsec;
if (t.tv_nsec >= 1000000000) {
t.tv_sec += 1;
@ -509,7 +509,7 @@ IBOOL S_condition_wait(c, m, t) s_thread_cond_t *c; scheme_mutex_t *m; ptr t; {
s_thread_t self = s_thread_self();
iptr count;
INT typeno;
long sec;
I64 sec;
long nsec;
INT status;
IBOOL is_collect;
@ -524,7 +524,7 @@ IBOOL S_condition_wait(c, m, t) s_thread_cond_t *c; scheme_mutex_t *m; ptr t; {
if (t != Sfalse) {
/* Keep in sync with ts record in s/date.ss */
typeno = Sinteger32_value(Srecord_ref(t,0));
sec = Sinteger32_value(Scar(Srecord_ref(t,1)));
sec = Sinteger64_value(Scar(Srecord_ref(t,1)));
nsec = Sinteger32_value(Scdr(Srecord_ref(t,1)));
} else {
typeno = 0;