Allow customization of softkill time via property SoftKillWaitSeconds and share time among processes when terminating a tree on linux
@@ -144,7 +144,7 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree,
*/
public abstract void killAll(Map<String, String> modelEnvVars) throws InterruptedException;
- private final int softkillWaitSeconds = 2 * 60; // processes get at most 2 minutes to respond to SIGTERM (JENKINS-17116)
+ private final long softKillWaitSeconds = Integer.getInteger("SoftKillWaitSeconds", 2 * 60); // by default processes get at most 2 minutes to respond to SIGTERM (JENKINS-17116)
/**
* Convenience method that does {@link #killAll(Map)} and {@link OSProcess#killRecursively()}.
@@ -537,7 +537,7 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree,
}
// after that wait for it to cease to exist
- long deadline = System.nanoTime() + softkillWaitSeconds * 1000000000;
+ long deadline = System.nanoTime() + softKillWaitSeconds * 1000000000;
int sleepTime = 10; // initially we sleep briefly, then sleep up to 1sec
do {
if (!p.isRunning()) {
@@ -751,6 +751,12 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree,
* Tries to kill this process.
*/
public void kill() throws InterruptedException {
+ // after sending SIGTERM, wait for the process to cease to exist
+ long deadline = System.nanoTime() + softKillWaitSeconds * 1000000000;
+ kill(deadline);
+ }
+
+ private void kill(long deadline) throws InterruptedException {
if (getVeto() != null)
return;
try {
@@ -758,11 +764,10 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree,
LOGGER.fine("Killing pid="+pid);
UnixReflection.destroy(pid);
// after sending SIGTERM, wait for the process to cease to exist
- long deadline = System.nanoTime() + softkillWaitSeconds * 1000000000;
int sleepTime = 10; // initially we sleep briefly, then sleep up to 1sec
+ File status = getFile("status");
do {
- File f = getFile("status");
- if (!f.exists()) {
+ if (!status.exists()) {
break; // status is gone, process therefore as well
}
@@ -785,11 +790,22 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree,
}
public void killRecursively() throws InterruptedException {
+ // after sending SIGTERM, wait for the processes to cease to exist until the deadline
+ long deadline = System.nanoTime() + softKillWaitSeconds * 1000000000;
+ killRecursively(deadline);
+ }
+
+ private void killRecursively(long deadline) throws InterruptedException {
// We kill individual processes of a tree, so handling vetoes inside #kill() is enough for UnixProcess es
LOGGER.fine("Recursively killing pid="+getPid());
- for (OSProcess p : getChildren())
- p.killRecursively();
- kill();
+ for (OSProcess p : getChildren()) {
+ if (p instanceof UnixProcess) {
+ ((UnixProcess)p).killRecursively(deadline);
+ } else {
+ p.killRecursively(); // should not happen, fallback to non-deadline version
+ }
+ }
+ kill(deadline);
}
/**
