aboutsummaryrefslogtreecommitdiff
path: root/libjava
diff options
context:
space:
mode:
authorAndrew Haley <aph@redhat.com>2005-11-25 16:18:17 +0000
committerAndrew Haley <aph@gcc.gnu.org>2005-11-25 16:18:17 +0000
commitca146b8fdf158dac07f949dc9b99107570d5f527 (patch)
tree5730d010703bbf05e5f347b66fc3c88ff22002eb /libjava
parente7e531924324c744fd5bce4aef999ad99fbc8f61 (diff)
downloadgcc-ca146b8fdf158dac07f949dc9b99107570d5f527.zip
gcc-ca146b8fdf158dac07f949dc9b99107570d5f527.tar.gz
gcc-ca146b8fdf158dac07f949dc9b99107570d5f527.tar.bz2
re PR libgcj/25016 (Integer overflow in _Jv_CondWait)
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. From-SVN: r107509
Diffstat (limited to 'libjava')
-rw-r--r--libjava/ChangeLog6
-rw-r--r--libjava/posix-threads.cc29
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 ();