diff --git a/racket/src/ChezScheme/LOG b/racket/src/ChezScheme/LOG index fb55caef59..79c1b5912d 100644 --- a/racket/src/ChezScheme/LOG +++ b/racket/src/ChezScheme/LOG @@ -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 diff --git a/racket/src/ChezScheme/c/thread.c b/racket/src/ChezScheme/c/thread.c index 39c0c8d7bb..92a58f565a 100644 --- a/racket/src/ChezScheme/c/thread.c +++ b/racket/src/ChezScheme/c/thread.c @@ -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;