/** *Interpretanarrayofstringsasacommandline. *@paramargsanarrayofstringstobeinterpretedascommands; *eachcommandusesadditionalargumentsasneeded
*/ privatestaticvoid interpretCommands(String[] args) { try { int nextArg = 0; while (nextArg < args.length) {
String action = args[nextArg++]; switch (action) { case"help":
sendResult(action, "");
help(); break; case"sleep": int millis = Integer.valueOf(args[nextArg++]); Thread.sleep(millis);
sendResult(action, Integer.toString(millis)); break; case"cpuloop": long cpuMillis = Long.valueOf(args[nextArg++]); long cpuTarget = getCpuTime() + cpuMillis * 1_000_000L; while (getCpuTime() < cpuTarget) { // burn the cpu until the time is up
}
sendResult(action, cpuMillis); break; case"cputime":
sendResult(action, getCpuTime()); break; case"out": case"err":
String value = args[nextArg++];
sendResult(action, value); if (action.equals("err")) {
System.err.println(value);
} break; case"stdin": // Read commands from stdin; at eof, close stdin of // children and wait for each to exit
sendResult(action, "start"); try (Reader reader = new InputStreamReader(System.in);
BufferedReader input = new BufferedReader(reader)) {
String line; while ((line = input.readLine()) != null) {
line = line.trim(); if (!line.isEmpty()) {
String[] split = line.split("\\s");
interpretCommands(split);
}
} // EOF on stdin, close stdin on all spawned processes for (JavaChild p : children) { try {
p.getOutputStream().close();
} catch (IOException ie) {
sendResult("stdin_closing", p.pid(), "exception", ie.getMessage());
}
}
for (JavaChild p : children) { do { try {
p.waitFor(); break;
} catch (InterruptedException e) { // retry
}
} while (true);
} // Wait for all children to be gone
Instant timeOut = Instant.now().plusSeconds(10L); while (!completedChildren.containsAll(children)) { if (Instant.now().isBefore(timeOut)) { Thread.sleep(100L);
} else {
System.err.printf("Timeout waiting for " + "children to terminate%n");
children.removeAll(completedChildren); for (JavaChild c : children) {
sendResult("stdin_noterm", c.pid());
System.err.printf(" Process not terminated: " + "pid: %d%n", c.pid());
}
System.exit(2);
}
}
}
sendResult(action, "done"); return; // normal exit from JavaChild Process case"parent":
sendResult(action, self.parent().toString()); break; case"pid":
sendResult(action, self.toString()); break; case"exit": int exitValue = (nextArg < args.length)
? Integer.valueOf(args[nextArg]) : 0;
sendResult(action, exitValue);
System.exit(exitValue); break; case"spawn": { if (args.length - nextArg < 2) { thrownew RuntimeException("not enough args for respawn: " +
(args.length - 2));
} // Spawn as many children as requested and // pass on rest of the arguments int ncount = Integer.valueOf(args[nextArg++]);
Object[] subargs = new String[args.length - nextArg];
System.arraycopy(args, nextArg, subargs, 0, subargs.length); for (int i = 0; i < ncount; i++) {
JavaChild p = spawnJavaChild(subargs);
sendResult(action, p.pid());
p.forEachOutputLine(JavaChild::sendRaw);
p.onJavaChildExit().thenAccept((p1) -> { int excode = p1.exitValue();
sendResult("child_exit", p1.pid(), excode);
completedChildren.add(p1);
});
children.add(p); // Add child to spawned list
}
nextArg = args.length; break;
} case"child": { // Send the command to all the live children; // ignoring those that are not alive int sentCount = 0;
Object[] result =
Arrays.copyOfRange(args, nextArg - 1, args.length);
Object[] subargs =
Arrays.copyOfRange(args, nextArg + 1, args.length); for (JavaChild p : children) { if (p.isAlive()) {
sentCount++; // overwrite with current pid
result[0] = Long.toString(p.pid());
sendResult(action, result);
p.sendAction(args[nextArg], subargs);
}
} if (sentCount == 0) {
sendResult(action, "n/a");
}
nextArg = args.length; break;
} case"child_eof" : // Close the InputStream of all the live children; // ignoring those that are not alive for (JavaChild p : children) { if (p.isAlive()) {
sendResult(action, p.pid());
p.getOutputStream().close();
}
} break; case"property":
String name = args[nextArg++];
sendResult(action, name, System.getProperty(name)); break; case"threaddump": Thread.dumpStack(); break; case"waitpid": long pid = Long.parseLong(args[nextArg++]);
Optional<String> s = ProcessHandle.of(pid).map(ph -> waitAlive(ph));
sendResult(action, s.orElse("pid not valid: " + pid)); break; default: thrownew Error("JavaChild action unknown: " + action);
}
}
} catch (Throwable t) {
t.printStackTrace(System.err);
System.exit(1);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.