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