Integer overflow in _Jv_CondWait
Andrew Haley
aph@redhat.com
Thu Nov 24 14:48:00 GMT 2005
This is the same patch, reworked slightly after feedback from gcj
developers.
I'm going to commit this in three places: trunk, 4.0, and 4.1.
Andrew.
2005-11-24 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.
(_Jv_CondWait):
Index: posix-threads.cc
===================================================================
--- posix-threads.cc (revision 106946)
+++ posix-threads.cc (working copy)
@@ -92,14 +92,33 @@
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 ();
More information about the Java-patches
mailing list