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

Print this page

        

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
+ * 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

@@ -36,10 +36,11 @@
 import java.io.OutputStream;
 import java.util.Arrays;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Executor;
 import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
 import java.security.AccessController;
 import static java.security.AccessController.doPrivileged;
 import java.security.PrivilegedAction;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;

@@ -210,34 +211,68 @@
             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(Math.max(TimeUnit.NANOSECONDS.toMillis(rem), 1));
+            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);
-    public void destroy() {
+    private static native void destroyProcess(int pid, boolean force);
+    private 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.
         synchronized (this) {
             if (!hasExited)
-                destroyProcess(pid);
+                destroyProcess(pid, force);
         }
         try { stdin.close();  } catch (IOException ignored) {}
         try { stdout.close(); } catch (IOException ignored) {}
         try { stderr.close(); } catch (IOException ignored) {}
     }
 
+    public void destroy() {
+        destroy(false);
+    }
+
+    @Override
+    public Process destroyForcibly() {
+        destroy(true);
+        return this;
+    }
+
+    @Override
+    public synchronized boolean isAlive() {
+        return !hasExited;
+    }
+
     /* This routine initializes JNI field offsets for the class */
     private static native void initIDs();
 
     static {
         initIDs();