From ca146b8fdf158dac07f949dc9b99107570d5f527 Mon Sep 17 00:00:00 2001 From: Andrew Haley Date: Fri, 25 Nov 2005 16:18:17 +0000 Subject: re PR libgcj/25016 (Integer overflow in _Jv_CondWait) 2005-11-25 Andrew Haley PR libgcj/25016 * posix-threads.cc (_Jv_CondWait): Rewrite calculation of the struct timespec we pass to pthread_cond_timedwait. From-SVN: r107509 --- libjava/ChangeLog | 6 ++++++ libjava/posix-threads.cc | 29 ++++++++++++++++++++++++----- 2 files changed, 30 insertions(+), 5 deletions(-) (limited to 'libjava') diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 82aceeb..73eadf4 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,9 @@ +2005-11-25 Andrew Haley + + PR libgcj/25016 + * posix-threads.cc (_Jv_CondWait): Rewrite calculation of the + struct timespec we pass to pthread_cond_timedwait. + 2005-11-25 Ranjit Mathew * testsuite/libjava.jacks/jacks.xfail: Remove diff --git a/libjava/posix-threads.cc b/libjava/posix-threads.cc index a596c77..042370f 100644 --- a/libjava/posix-threads.cc +++ b/libjava/posix-threads.cc @@ -92,14 +92,33 @@ _Jv_CondWait (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu, return _JV_NOT_OWNER; struct timespec ts; - jlong m, startTime; if (millis > 0 || nanos > 0) { - startTime = java::lang::System::currentTimeMillis(); - m = millis + startTime; - ts.tv_sec = m / 1000; - ts.tv_nsec = ((m % 1000) * 1000000) + nanos; + // Calculate the abstime corresponding to the timeout. + // Everything is in milliseconds. + // + // We use `unsigned long long' rather than jlong because our + // caller may pass up to Long.MAX_VALUE millis. This would + // overflow the range of a jlong when added to the current time. + + unsigned long long startTime + = (unsigned long long)java::lang::System::currentTimeMillis(); + unsigned long long m = (unsigned long long)millis + startTime; + unsigned long long seconds = m / 1000; + + ts.tv_sec = seconds; + if (ts.tv_sec < 0 || (unsigned long long)ts.tv_sec != seconds) + { + // We treat a timeout that won't fit into a struct timespec + // as a wait forever. + millis = nanos = 0; + } + else + { + m %= 1000; + ts.tv_nsec = m * 1000000 + (unsigned long long)nanos; + } } _Jv_Thread_t *current = _Jv_ThreadCurrentData (); -- cgit v1.1