# HG changeset patch # User rriggs # Date 1534343907 14400 # Node ID 41257a58a58822d943c6dbe081e919f490fa96c1 # Parent ef57958c7c511162da8d9a75f0b977f0f7ac464e 8208715: Conversion of milliseconds to nanoseconds in UNIXProcess contains bug Reviewed-by: martin diff -r ef57958c7c51 -r 41257a58a588 src/java.base/unix/classes/java/lang/ProcessImpl.java --- a/src/java.base/unix/classes/java/lang/ProcessImpl.java Thu Aug 16 16:06:54 2018 +0530 +++ b/src/java.base/unix/classes/java/lang/ProcessImpl.java Wed Aug 15 10:38:27 2018 -0400 @@ -507,8 +507,7 @@ long deadline = System.nanoTime() + remainingNanos; do { - // Round up to next millisecond - wait(TimeUnit.NANOSECONDS.toMillis(remainingNanos + 999_999L)); + TimeUnit.NANOSECONDS.timedWait(this, remainingNanos); if (hasExited) { return true; } diff -r ef57958c7c51 -r 41257a58a588 src/java.base/windows/classes/java/lang/ProcessImpl.java --- a/src/java.base/windows/classes/java/lang/ProcessImpl.java Thu Aug 16 16:06:54 2018 +0530 +++ b/src/java.base/windows/classes/java/lang/ProcessImpl.java Wed Aug 15 10:38:27 2018 -0400 @@ -497,10 +497,14 @@ if (getExitCodeProcess(handle) != STILL_ACTIVE) return true; if (timeout <= 0) return false; - long deadline = System.nanoTime() + remainingNanos ; + long deadline = System.nanoTime() + remainingNanos; do { // Round up to next millisecond long msTimeout = TimeUnit.NANOSECONDS.toMillis(remainingNanos + 999_999L); + if (msTimeout < 0) { + // if wraps around then wait a long while + msTimeout = Integer.MAX_VALUE; + } waitForTimeoutInterruptibly(handle, msTimeout); if (Thread.interrupted()) throw new InterruptedException(); @@ -514,7 +518,7 @@ } private static native void waitForTimeoutInterruptibly( - long handle, long timeout); + long handle, long timeoutMillis); @Override public void destroy() { diff -r ef57958c7c51 -r 41257a58a588 src/java.base/windows/native/libjava/ProcessImpl_md.c --- a/src/java.base/windows/native/libjava/ProcessImpl_md.c Thu Aug 16 16:06:54 2018 +0530 +++ b/src/java.base/windows/native/libjava/ProcessImpl_md.c Wed Aug 15 10:38:27 2018 -0400 @@ -433,10 +433,10 @@ Java_java_lang_ProcessImpl_waitForTimeoutInterruptibly(JNIEnv *env, jclass ignored, jlong handle, - jlong timeout) + jlong timeoutMillis) { HANDLE events[2]; - DWORD dwTimeout = (DWORD)timeout; + DWORD dwTimeout = (DWORD)timeoutMillis; DWORD result; events[0] = (HANDLE) handle; events[1] = JVM_GetThreadInterruptEvent(); diff -r ef57958c7c51 -r 41257a58a588 test/jdk/java/lang/ProcessBuilder/Basic.java --- a/test/jdk/java/lang/ProcessBuilder/Basic.java Thu Aug 16 16:06:54 2018 +0530 +++ b/test/jdk/java/lang/ProcessBuilder/Basic.java Wed Aug 15 10:38:27 2018 -0400 @@ -2421,6 +2421,7 @@ public void run() { try { aboutToWaitFor.countDown(); + Thread.currentThread().interrupt(); boolean result = p.waitFor(30L * 1000L, TimeUnit.MILLISECONDS); fail("waitFor() wasn't interrupted, its return value was: " + result); } catch (InterruptedException success) { @@ -2430,7 +2431,38 @@ thread.start(); aboutToWaitFor.await(); - Thread.sleep(1000); + thread.interrupt(); + thread.join(10L * 1000L); + check(millisElapsedSince(start) < 10L * 1000L); + check(!thread.isAlive()); + p.destroy(); + } catch (Throwable t) { unexpected(t); } + + //---------------------------------------------------------------- + // Check that Process.waitFor(Long.MAX_VALUE, TimeUnit.MILLISECONDS) + // interrupt works as expected, if interrupted while waiting. + //---------------------------------------------------------------- + try { + List childArgs = new ArrayList(javaChildArgs); + childArgs.add("sleep"); + final Process p = new ProcessBuilder(childArgs).start(); + final long start = System.nanoTime(); + final CountDownLatch aboutToWaitFor = new CountDownLatch(1); + + final Thread thread = new Thread() { + public void run() { + try { + aboutToWaitFor.countDown(); + Thread.currentThread().interrupt(); + boolean result = p.waitFor(Long.MAX_VALUE, TimeUnit.MILLISECONDS); + fail("waitFor() wasn't interrupted, its return value was: " + result); + } catch (InterruptedException success) { + } catch (Throwable t) { unexpected(t); } + } + }; + + thread.start(); + aboutToWaitFor.await(); thread.interrupt(); thread.join(10L * 1000L); check(millisElapsedSince(start) < 10L * 1000L);