src/solaris/classes/java/lang/UNIXProcess.java.solaris

Print this page

        

*** 1,7 **** /* ! * Copyright (c) 1995, 2010, 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 --- 1,7 ---- /* ! * Copyright (c) 1995, 2012, 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
*** 24,33 **** --- 24,34 ---- */ package java.lang; import java.io.*; + import java.util.concurrent.TimeUnit; /* java.lang.Process subclass in the UNIX environment. * * @author Mario Wolczko and Ross Knippel. */
*** 156,182 **** wait(); } return exitcode; } public synchronized int exitValue() { if (!hasExited) { throw new IllegalThreadStateException("process hasn't exited"); } return exitcode; } ! private static native void destroyProcess(int pid); ! public synchronized void destroy() { // There is a risk that pid will be recycled, causing us to // kill the wrong process! So we only terminate processes // that appear to still be running. Even with this check, // there is an unavoidable race condition here, but the window // is very small, and OSes try hard to not recycle pids too // soon, so this is quite safe. if (!hasExited) ! destroyProcess(pid); try { stdin_stream.close(); if (stdout_inner_stream != null) stdout_inner_stream.closeDeferred(stdout_stream); if (stderr_stream instanceof DeferredCloseInputStream) --- 157,202 ---- wait(); } return exitcode; } + @Override + public synchronized boolean waitFor(long timeout, TimeUnit unit) + throws InterruptedException { + if (hasExited) return true; + if (timeout <= 0) return false; + + long now = System.nanoTime(); + long end = now + TimeUnit.NANOSECONDS.convert(timeout, unit); + if (end <= 0) // overflow + end = Long.MAX_VALUE; + + long rem = end - now; + while (!hasExited && (rem > 0)) { + wait(TimeUnit.NANOSECONDS.toMillis(rem)); + rem = end - System.nanoTime(); + } + return hasExited; + } + public synchronized int exitValue() { if (!hasExited) { throw new IllegalThreadStateException("process hasn't exited"); } return exitcode; } ! private static native void destroyProcess(int pid, boolean force); ! private synchronized void destroy(boolean force) { // There is a risk that pid will be recycled, causing us to // kill the wrong process! So we only terminate processes // that appear to still be running. Even with this check, // there is an unavoidable race condition here, but the window // is very small, and OSes try hard to not recycle pids too // soon, so this is quite safe. if (!hasExited) ! destroyProcess(pid, force); try { stdin_stream.close(); if (stdout_inner_stream != null) stdout_inner_stream.closeDeferred(stdout_stream); if (stderr_stream instanceof DeferredCloseInputStream)
*** 185,194 **** --- 205,229 ---- } catch (IOException e) { // ignore } } + public void destroy() { + destroy(false); + } + + @Override + public Process destroyForcibly() { + destroy(true); + return this; + } + + @Override + public synchronized boolean isAlive() { + return !hasExited; + } + // A FileInputStream that supports the deferment of the actual close // operation until the last pending I/O operation on the stream has // finished. This is required on Solaris because we must close the stdin // and stdout streams in the destroy method in order to reclaim the // underlying file descriptors. Doing so, however, causes any thread