mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8208715: Conversion of milliseconds to nanoseconds in UNIXProcess contains bug
Reviewed-by: martin
This commit is contained in:
parent
8cf153fbd5
commit
63b1edb7b7
4 changed files with 42 additions and 7 deletions
|
@ -507,8 +507,7 @@ final class ProcessImpl extends Process {
|
||||||
|
|
||||||
long deadline = System.nanoTime() + remainingNanos;
|
long deadline = System.nanoTime() + remainingNanos;
|
||||||
do {
|
do {
|
||||||
// Round up to next millisecond
|
TimeUnit.NANOSECONDS.timedWait(this, remainingNanos);
|
||||||
wait(TimeUnit.NANOSECONDS.toMillis(remainingNanos + 999_999L));
|
|
||||||
if (hasExited) {
|
if (hasExited) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -497,10 +497,14 @@ final class ProcessImpl extends Process {
|
||||||
if (getExitCodeProcess(handle) != STILL_ACTIVE) return true;
|
if (getExitCodeProcess(handle) != STILL_ACTIVE) return true;
|
||||||
if (timeout <= 0) return false;
|
if (timeout <= 0) return false;
|
||||||
|
|
||||||
long deadline = System.nanoTime() + remainingNanos ;
|
long deadline = System.nanoTime() + remainingNanos;
|
||||||
do {
|
do {
|
||||||
// Round up to next millisecond
|
// Round up to next millisecond
|
||||||
long msTimeout = TimeUnit.NANOSECONDS.toMillis(remainingNanos + 999_999L);
|
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);
|
waitForTimeoutInterruptibly(handle, msTimeout);
|
||||||
if (Thread.interrupted())
|
if (Thread.interrupted())
|
||||||
throw new InterruptedException();
|
throw new InterruptedException();
|
||||||
|
@ -514,7 +518,7 @@ final class ProcessImpl extends Process {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static native void waitForTimeoutInterruptibly(
|
private static native void waitForTimeoutInterruptibly(
|
||||||
long handle, long timeout);
|
long handle, long timeoutMillis);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
|
|
|
@ -433,10 +433,10 @@ JNIEXPORT void JNICALL
|
||||||
Java_java_lang_ProcessImpl_waitForTimeoutInterruptibly(JNIEnv *env,
|
Java_java_lang_ProcessImpl_waitForTimeoutInterruptibly(JNIEnv *env,
|
||||||
jclass ignored,
|
jclass ignored,
|
||||||
jlong handle,
|
jlong handle,
|
||||||
jlong timeout)
|
jlong timeoutMillis)
|
||||||
{
|
{
|
||||||
HANDLE events[2];
|
HANDLE events[2];
|
||||||
DWORD dwTimeout = (DWORD)timeout;
|
DWORD dwTimeout = (DWORD)timeoutMillis;
|
||||||
DWORD result;
|
DWORD result;
|
||||||
events[0] = (HANDLE) handle;
|
events[0] = (HANDLE) handle;
|
||||||
events[1] = JVM_GetThreadInterruptEvent();
|
events[1] = JVM_GetThreadInterruptEvent();
|
||||||
|
|
|
@ -2421,6 +2421,7 @@ public class Basic {
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
aboutToWaitFor.countDown();
|
aboutToWaitFor.countDown();
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
boolean result = p.waitFor(30L * 1000L, TimeUnit.MILLISECONDS);
|
boolean result = p.waitFor(30L * 1000L, TimeUnit.MILLISECONDS);
|
||||||
fail("waitFor() wasn't interrupted, its return value was: " + result);
|
fail("waitFor() wasn't interrupted, its return value was: " + result);
|
||||||
} catch (InterruptedException success) {
|
} catch (InterruptedException success) {
|
||||||
|
@ -2430,7 +2431,38 @@ public class Basic {
|
||||||
|
|
||||||
thread.start();
|
thread.start();
|
||||||
aboutToWaitFor.await();
|
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.interrupt();
|
||||||
thread.join(10L * 1000L);
|
thread.join(10L * 1000L);
|
||||||
check(millisElapsedSince(start) < 10L * 1000L);
|
check(millisElapsedSince(start) < 10L * 1000L);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue