Home | History | Annotate | Download | only in src
      1 import java.util.Map;
      2 
      3 public class Main {
      4     static public void main(String[] args) throws Exception {
      5         checkManager();
      6 
      7         // Warm up the reaper so that there are no issues with scheduling because of static
      8         // initialization.
      9         {
     10             ProcessBuilder pb = new ProcessBuilder("sleep", "0");
     11             Process proc = pb.start();
     12             proc.waitFor();
     13             waitForReaperTimedWaiting(true /* reaperMustExist */);
     14         }
     15 
     16         for (int i = 1; i <= 2; i++) {
     17             System.out.println("\nspawning child #" + i);
     18             child();
     19             Thread.sleep(2000);
     20             checkManager();
     21         }
     22         System.out.println("\ndone!");
     23     }
     24 
     25     static private void child() throws Exception {
     26         System.out.println("spawning child");
     27         ProcessBuilder pb = new ProcessBuilder("sleep", "5");
     28         Process proc = pb.start();
     29         Thread.sleep(250);
     30         checkManager();
     31         proc.waitFor();
     32         System.out.println("child died");
     33     }
     34 
     35     private static boolean isReaperThread(Thread t) {
     36         String name = t.getName();
     37         return name.indexOf("process reaper") >= 0;
     38     }
     39 
     40     static private void checkManager() {
     41         Map<Thread, StackTraceElement[]> traces = Thread.getAllStackTraces();
     42         boolean found = false;
     43 
     44         for (Map.Entry<Thread, StackTraceElement[]> entry :
     45                  traces.entrySet()) {
     46             Thread t = entry.getKey();
     47             if (isReaperThread(t)) {
     48                 Thread.State state = t.getState();
     49                 System.out.println("process manager: " + state);
     50                 if (state != Thread.State.RUNNABLE && state != Thread.State.TIMED_WAITING) {
     51                     for (StackTraceElement e : entry.getValue()) {
     52                         System.out.println("  " + e);
     53                     }
     54                 }
     55                 found = true;
     56             }
     57         }
     58 
     59         if (! found) {
     60             System.out.println("process manager: nonexistent");
     61         }
     62     }
     63 
     64     private static void waitForReaperTimedWaiting(boolean reaperMustExist) {
     65         for (;;) {
     66             Map<Thread, StackTraceElement[]> traces = Thread.getAllStackTraces();
     67 
     68             boolean ok = true;
     69             boolean found = false;
     70 
     71             for (Thread t : traces.keySet()) {
     72                 if (isReaperThread(t)) {
     73                     found = true;
     74                     Thread.State state = t.getState();
     75                     if (state != Thread.State.TIMED_WAITING) {
     76                         ok = false;
     77                         break;
     78                     }
     79                 }
     80             }
     81 
     82             if (ok && (!reaperMustExist || found)) {
     83                 return;
     84             }
     85 
     86             try {
     87                 Thread.sleep(100);
     88             } catch (Exception e) {
     89                 // Ignore.
     90             }
     91         }
     92     }
     93 }
     94