< prev index next >
src/java.base/share/classes/java/lang/Process.java
Print this page
rev 54134 : [mq]: 8220684-Process-waitFor-long-TimeUnit-can-return-false-for-a-process-that-exited-within-the-timeout
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 1995, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
@@ -204,24 +204,20 @@
* @since 1.8
*/
public boolean waitFor(long timeout, TimeUnit unit)
throws InterruptedException
{
- long startTime = System.nanoTime();
- long rem = unit.toNanos(timeout);
+ long remainingNanos = unit.toNanos(timeout); // throw NPE before other conditions
+ if (hasExited()) return true;
+ if (timeout <= 0) return false;
+ long deadline = System.nanoTime() + remainingNanos;
do {
- try {
- exitValue();
- return true;
- } catch(IllegalThreadStateException ex) {
- if (rem > 0)
- Thread.sleep(
- Math.min(TimeUnit.NANOSECONDS.toMillis(rem) + 1, 100));
- }
- rem = unit.toNanos(timeout) - (System.nanoTime() - startTime);
- } while (rem > 0);
+ Thread.sleep(Math.min(TimeUnit.NANOSECONDS.toMillis(remainingNanos) + 1, 100));
+ if (hasExited()) return true;
+ remainingNanos = deadline - System.nanoTime();
+ } while (remainingNanos > 0);
return false;
}
/**
* Returns the exit value for the process.
@@ -318,15 +314,24 @@
* @return {@code true} if the process represented by this
* {@code Process} object has not yet terminated.
* @since 1.8
*/
public boolean isAlive() {
+ return !hasExited();
+ }
+
+ /**
+ * This is called from the default implementation of
+ * {@code waitFor(long, TimeUnit)}, which is specified to poll
+ * {@code exitValue()}.
+ */
+ private boolean hasExited() {
try {
exitValue();
- return false;
- } catch(IllegalThreadStateException e) {
return true;
+ } catch (IllegalThreadStateException e) {
+ return false;
}
}
/**
* Returns the native process ID of the process.
< prev index next >