8208715: Conversion of milliseconds to nanoseconds in UNIXProcess contains bug

Reviewed-by: martin
This commit is contained in:
Roger Riggs 2018-08-15 10:38:27 -04:00
parent 8cf153fbd5
commit 63b1edb7b7
4 changed files with 42 additions and 7 deletions
src/java.base
unix/classes/java/lang
windows
classes/java/lang
native/libjava
test/jdk/java/lang/ProcessBuilder

@ -507,8 +507,7 @@ final class ProcessImpl extends Process {
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;
}

@ -497,10 +497,14 @@ final class ProcessImpl extends Process {
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 @@ final class ProcessImpl extends Process {
}
private static native void waitForTimeoutInterruptibly(
long handle, long timeout);
long handle, long timeoutMillis);
@Override
public void destroy() {

@ -433,10 +433,10 @@ JNIEXPORT void JNICALL
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();

@ -2421,6 +2421,7 @@ public class Basic {
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 @@ public class Basic {
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<String> childArgs = new ArrayList<String>(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);