< 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 /*
   2  * Copyright (c) 1995, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 189      * terminated and the timeout value is less than, or equal to, zero, then
 190      * this method returns immediately with the value {@code false}.
 191      *
 192      * <p>The default implementation of this methods polls the {@code exitValue}
 193      * to check if the process has terminated. Concrete implementations of this
 194      * class are strongly encouraged to override this method with a more
 195      * efficient implementation.
 196      *
 197      * @param timeout the maximum time to wait
 198      * @param unit the time unit of the {@code timeout} argument
 199      * @return {@code true} if the process has exited and {@code false} if
 200      *         the waiting time elapsed before the process has exited.
 201      * @throws InterruptedException if the current thread is interrupted
 202      *         while waiting.
 203      * @throws NullPointerException if unit is null
 204      * @since 1.8
 205      */
 206     public boolean waitFor(long timeout, TimeUnit unit)
 207         throws InterruptedException
 208     {
 209         long startTime = System.nanoTime();
 210         long rem = unit.toNanos(timeout);

 211 

 212         do {
 213             try {
 214                 exitValue();
 215                 return true;
 216             } catch(IllegalThreadStateException ex) {
 217                 if (rem > 0)
 218                     Thread.sleep(
 219                         Math.min(TimeUnit.NANOSECONDS.toMillis(rem) + 1, 100));
 220             }
 221             rem = unit.toNanos(timeout) - (System.nanoTime() - startTime);
 222         } while (rem > 0);
 223         return false;
 224     }
 225 
 226     /**
 227      * Returns the exit value for the process.
 228      *
 229      * @return the exit value of the process represented by this
 230      *         {@code Process} object.  By convention, the value
 231      *         {@code 0} indicates normal termination.
 232      * @throws IllegalThreadStateException if the process represented
 233      *         by this {@code Process} object has not yet terminated
 234      */
 235     public abstract int exitValue();
 236 
 237     /**
 238      * Kills the process.
 239      * Whether the process represented by this {@code Process} object is
 240      * {@linkplain #supportsNormalTermination normally terminated} or not is
 241      * implementation dependent.
 242      * Forcible process destruction is defined as the immediate termination of a


 303      *         normally terminate the process;
 304      *         otherwise, {@link #destroy} forcibly terminates the process
 305      * @throws UnsupportedOperationException if the Process implementation
 306      *         does not support this operation
 307      * @since 9
 308      */
 309     public boolean supportsNormalTermination() {
 310         throw new UnsupportedOperationException(this.getClass()
 311                 + ".supportsNormalTermination() not supported" );
 312     }
 313 
 314     /**
 315      * Tests whether the process represented by this {@code Process} is
 316      * alive.
 317      *
 318      * @return {@code true} if the process represented by this
 319      *         {@code Process} object has not yet terminated.
 320      * @since 1.8
 321      */
 322     public boolean isAlive() {









 323         try {
 324             exitValue();
 325             return false;
 326         } catch(IllegalThreadStateException e) {
 327             return true;


 328         }
 329     }
 330 
 331     /**
 332      * Returns the native process ID of the process.
 333      * The native process ID is an identification number that the operating
 334      * system assigns to the process.
 335      *
 336      * @implSpec
 337      * The implementation of this method returns the process id as:
 338      * {@link #toHandle toHandle().pid()}.
 339      *
 340      * @return the native process id of the process
 341      * @throws UnsupportedOperationException if the Process implementation
 342      *         does not support this operation
 343      * @since 9
 344      */
 345     public long pid() {
 346         return toHandle().pid();
 347     }


   1 /*
   2  * Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 189      * terminated and the timeout value is less than, or equal to, zero, then
 190      * this method returns immediately with the value {@code false}.
 191      *
 192      * <p>The default implementation of this methods polls the {@code exitValue}
 193      * to check if the process has terminated. Concrete implementations of this
 194      * class are strongly encouraged to override this method with a more
 195      * efficient implementation.
 196      *
 197      * @param timeout the maximum time to wait
 198      * @param unit the time unit of the {@code timeout} argument
 199      * @return {@code true} if the process has exited and {@code false} if
 200      *         the waiting time elapsed before the process has exited.
 201      * @throws InterruptedException if the current thread is interrupted
 202      *         while waiting.
 203      * @throws NullPointerException if unit is null
 204      * @since 1.8
 205      */
 206     public boolean waitFor(long timeout, TimeUnit unit)
 207         throws InterruptedException
 208     {
 209         long remainingNanos = unit.toNanos(timeout);    // throw NPE before other conditions
 210         if (hasExited()) return true;
 211         if (timeout <= 0) return false;
 212 
 213         long deadline = System.nanoTime() + remainingNanos;
 214         do {
 215             Thread.sleep(Math.min(TimeUnit.NANOSECONDS.toMillis(remainingNanos) + 1, 100));
 216             if (hasExited()) return true;
 217             remainingNanos = deadline - System.nanoTime();
 218         } while (remainingNanos > 0);






 219         return false;
 220     }
 221 
 222     /**
 223      * Returns the exit value for the process.
 224      *
 225      * @return the exit value of the process represented by this
 226      *         {@code Process} object.  By convention, the value
 227      *         {@code 0} indicates normal termination.
 228      * @throws IllegalThreadStateException if the process represented
 229      *         by this {@code Process} object has not yet terminated
 230      */
 231     public abstract int exitValue();
 232 
 233     /**
 234      * Kills the process.
 235      * Whether the process represented by this {@code Process} object is
 236      * {@linkplain #supportsNormalTermination normally terminated} or not is
 237      * implementation dependent.
 238      * Forcible process destruction is defined as the immediate termination of a


 299      *         normally terminate the process;
 300      *         otherwise, {@link #destroy} forcibly terminates the process
 301      * @throws UnsupportedOperationException if the Process implementation
 302      *         does not support this operation
 303      * @since 9
 304      */
 305     public boolean supportsNormalTermination() {
 306         throw new UnsupportedOperationException(this.getClass()
 307                 + ".supportsNormalTermination() not supported" );
 308     }
 309 
 310     /**
 311      * Tests whether the process represented by this {@code Process} is
 312      * alive.
 313      *
 314      * @return {@code true} if the process represented by this
 315      *         {@code Process} object has not yet terminated.
 316      * @since 1.8
 317      */
 318     public boolean isAlive() {
 319         return !hasExited();
 320     }
 321 
 322     /**
 323      * This is called from the default implementation of
 324      * {@code waitFor(long, TimeUnit)}, which is specified to poll
 325      * {@code exitValue()}.
 326      */
 327     private boolean hasExited() {
 328         try {
 329             exitValue();


 330             return true;
 331         } catch (IllegalThreadStateException e) {
 332             return false;
 333         }
 334     }
 335 
 336     /**
 337      * Returns the native process ID of the process.
 338      * The native process ID is an identification number that the operating
 339      * system assigns to the process.
 340      *
 341      * @implSpec
 342      * The implementation of this method returns the process id as:
 343      * {@link #toHandle toHandle().pid()}.
 344      *
 345      * @return the native process id of the process
 346      * @throws UnsupportedOperationException if the Process implementation
 347      *         does not support this operation
 348      * @since 9
 349      */
 350     public long pid() {
 351         return toHandle().pid();
 352     }


< prev index next >