aboutsummaryrefslogtreecommitdiff
path: root/libjava/posix-threads.cc
diff options
context:
space:
mode:
authorAndrew Haley <aph@redhat.com>2005-11-25 16:18:17 +0000
committerAndrew Haley <aph@redhat.com>2005-11-25 16:18:17 +0000
commitc27db698bee816ebbb82250d3dd2e2e0ce40ea3d (patch)
tree5730d010703bbf05e5f347b66fc3c88ff22002eb /libjava/posix-threads.cc
parent5fd4d3821b6a60d628e1e1edcf9d9036dd543046 (diff)
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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@107509 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava/posix-threads.cc')
-rw-r--r--libjava/posix-threads.cc29
1 files changed, 24 insertions, 5 deletions
diff --git a/libjava/posix-threads.cc b/libjava/posix-threads.cc
index a596c77e131..042370fc379 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 ();