feisty meow concerns codebase  2.140
ThreadSpawnerAndWatcher.java
Go to the documentation of this file.
1 package org.feistymeow.process;
2 
4 //Name : ThreadSpawnerAndWatcher
5 //Author : Chris Koeritz
6 //Rights : Copyright (c) 2012-$now By University of Virginia
8 //This file is free software; you can modify/redistribute it under the terms
9 //of the Apache License v2.0: http://www.apache.org/licenses/LICENSE-2.0
10 //Feel free to send updates to: [ koeritz@virginia.edu ]
12 
13 
14 // test app by Chris Koeritz.
15 
16 import java.io.IOException;
17 import java.lang.ProcessBuilder;
18 import java.lang.Process;
19 import java.util.Vector;
20 
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.apache.log4j.PropertyConfigurator;
24 
25 class Defaults
26 {
27  public static int CONCURRENT_LAUNCHES = 1000;
28 };
29 
30 // will be spawned multiply and each one will check its one process.
31 class ThreadSpawnerAndWatcher implements Runnable
32 {
33  private static Log c_logger = LogFactory.getLog(ThreadSpawnerAndWatcher.class);
34 
35  private volatile Thread myThread;
36 
37  private Vector<String> cmdline;
38 
39  private ProcessBuilder procbuild;
40 
41  @SuppressWarnings("unchecked")
42  public ThreadSpawnerAndWatcher(Vector<String> command_line)
43  {
44  cmdline = (Vector<String>) command_line.clone();
45  procbuild = new ProcessBuilder(cmdline);
46  }
47 
51  public void start()
52  {
53  if (null == this.myThread) {
54  this.myThread = new Thread(this);
55  this.myThread.start();
56  }
57  }
58 
62  public void stop()
63  {
64  Thread goAway = myThread;
65  myThread = null;
66  if (null != goAway) {
67  goAway.interrupt();
68  }
69  }
70 
74  public boolean threadRunning()
75  {
76  return (null != this.myThread);
77  }
78 
79  public void run()
80  {
81  if (false == threadRunning()) {
82  return; // stopped before it ever started
83  }
84 
85  try {
86  // c_logger.info("about to start process: " + cmdline);
87  Process p = procbuild.start();
88  p.waitFor();
89  // c_logger.info("returned from awaiting process: " + cmdline);
90  } catch (IOException e) {
91  c_logger.debug("thread caught io exception on: " + cmdline);
92  } catch (InterruptedException ie) {
93  c_logger.debug("thread interrupted for: " + cmdline);
94  } finally {
95  this.myThread = null; // thread is exiting
96  }
97  }
98 
99  static public void main(String[] args) throws Throwable
100  {
101  PropertyConfigurator.configure("log4j.properties"); // hard-coded for
102  // eclipse based run.
103 
104  Vector<String> cmds = new Vector<String>();
105 
106  cmds.add("/bin/echo");
107  cmds.add("hello jupiter");
108 
109  // cmds.add("/bin/sleep");
110  // cmds.add("10");
111 
112  Vector<ThreadSpawnerAndWatcher> watchers = new Vector<ThreadSpawnerAndWatcher>();
113 
114  c_logger.info("revving up the process launching test.");
115 
116  // create all the threads and get them ready to go.
117  for (int i = 0; i < Defaults.CONCURRENT_LAUNCHES; i++) {
118  ThreadSpawnerAndWatcher newby = new ThreadSpawnerAndWatcher(cmds);
119  watchers.add(newby);
120  }
121 
122  // randomize start order?
123  // now start all the threads, which will cause all our process launches.
124  for (int i = 0; i < Defaults.CONCURRENT_LAUNCHES; i++) {
125  ThreadSpawnerAndWatcher curr = watchers.get(i);
126  curr.start();
127  }
128 
129  // now wait for them all to finish. if we never get out, then there's a bug
130  // someplace.
131  for (int i = 0; i < Defaults.CONCURRENT_LAUNCHES; i++) {
132  ThreadSpawnerAndWatcher curr = watchers.get(i);
133  while (curr.threadRunning()) {
134  try {
135  Thread.sleep(100);
136  } catch (InterruptedException e) {
137  // ignore for now.
138  }
139  }
140  }
141 
142  // currently test will never come back out to finish, if there's a failure
143  // seen.
144  c_logger.info("Test Succeeded: all spawned processes came back as expected.");
145  System.exit(0);
146  }
147 }