8064932: java/lang/ProcessBuilder/Basic.java: waitFor didn't take long enough
authorrriggs
Wed, 19 Nov 2014 21:22:22 -0500
changeset 27732 31d7da6e79bf
parent 27731 3cba975130c0
child 27733 e4e4d12307d7
8064932: java/lang/ProcessBuilder/Basic.java: waitFor didn't take long enough Reviewed-by: dholmes, martin
jdk/src/java.base/unix/classes/java/lang/UNIXProcess.java
jdk/src/java.base/windows/classes/java/lang/ProcessImpl.java
--- a/jdk/src/java.base/unix/classes/java/lang/UNIXProcess.java	Mon Nov 17 23:56:53 2014 +0100
+++ b/jdk/src/java.base/unix/classes/java/lang/UNIXProcess.java	Wed Nov 19 21:22:22 2014 -0500
@@ -406,14 +406,17 @@
         if (hasExited) return true;
         if (timeout <= 0) return false;
 
-        long timeoutAsNanos = unit.toNanos(timeout);
-        long startTime = System.nanoTime();
-        long rem = timeoutAsNanos;
+        long remainingNanos = unit.toNanos(timeout);
+        long deadline = System.nanoTime() + remainingNanos;
 
-        while (!hasExited && (rem > 0)) {
-            wait(Math.max(TimeUnit.NANOSECONDS.toMillis(rem), 1));
-            rem = timeoutAsNanos - (System.nanoTime() - startTime);
-        }
+        do {
+            // Round up to next millisecond
+            wait(TimeUnit.NANOSECONDS.toMillis(remainingNanos + 999_999L));
+            if (hasExited) {
+                return true;
+            }
+            remainingNanos = deadline - System.nanoTime();
+        } while (remainingNanos > 0);
         return hasExited;
     }
 
--- a/jdk/src/java.base/windows/classes/java/lang/ProcessImpl.java	Mon Nov 17 23:56:53 2014 +0100
+++ b/jdk/src/java.base/windows/classes/java/lang/ProcessImpl.java	Wed Nov 19 21:22:22 2014 -0500
@@ -461,11 +461,21 @@
         if (getExitCodeProcess(handle) != STILL_ACTIVE) return true;
         if (timeout <= 0) return false;
 
-        long msTimeout = unit.toMillis(timeout);
+        long remainingNanos  = unit.toNanos(timeout);
+        long deadline = System.nanoTime() + remainingNanos ;
 
-        waitForTimeoutInterruptibly(handle, msTimeout);
-        if (Thread.interrupted())
-            throw new InterruptedException();
+        do {
+            // Round up to next millisecond
+            long msTimeout = TimeUnit.NANOSECONDS.toMillis(remainingNanos + 999_999L);
+            waitForTimeoutInterruptibly(handle, msTimeout);
+            if (Thread.interrupted())
+                throw new InterruptedException();
+            if (getExitCodeProcess(handle) != STILL_ACTIVE) {
+                return true;
+            }
+            remainingNanos = deadline - System.nanoTime();
+        } while (remainingNanos > 0);
+
         return (getExitCodeProcess(handle) != STILL_ACTIVE);
     }