]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR libgcj/25016 (Integer overflow in _Jv_CondWait)
authorAndrew Haley <aph@redhat.com>
Fri, 25 Nov 2005 16:18:17 +0000 (16:18 +0000)
committerAndrew Haley <aph@gcc.gnu.org>
Fri, 25 Nov 2005 16:18:17 +0000 (16:18 +0000)
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

libjava/ChangeLog
libjava/posix-threads.cc

index 82aceeb5c0da193adea24a754cf4175479481205..73eadf43b6aa5a0eb750e34d14cfc13ce4273c32 100644 (file)
@@ -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
index a596c77e131c1778bb578c94891a7051803d99b7..042370fc37958c87c1fe26870610204d448da5a2 100644 (file)
@@ -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 ();