diff options
Diffstat (limited to 'libjava')
-rw-r--r-- | libjava/ChangeLog | 6 | ||||
-rw-r--r-- | libjava/posix-threads.cc | 29 |
2 files changed, 30 insertions, 5 deletions
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 <aph@redhat.com> + + 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 <rmathew@gcc.gnu.org> * 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 (); |