HomePhabricator

When stopping subprocesses, send SIGTERM first, then SIGKILL if that doesn't…

Description

When stopping subprocesses, send SIGTERM first, then SIGKILL if that doesn't work

Summary:
Fixes T11592. This improves our ability to clean up subprocess trees:

  • When killing a subprocess, send it SIGTERM first. If that doesn't work, wait a little while and send it SIGKILL.
  • When exiting via __destruct() (for example, in response to recieving SIGTERM ourselves) try to SIGTERM children. We wait a shorter period of time for them to exit in this case (5 seconds).

Test Plan:
Used several scripts that run one another:

test.php
<?php

require_once '../libphutil/scripts/__init_script__.php';

echo getmypid()."\n";

$future = new ExecFuture('php -f test2.php');
$future->setTimeout(1);
var_dump($future->resolve());
test2.php
<?php

require_once '../libphutil/scripts/__init_script__.php';

echo getmypid()."\n";

$future = new ExecFuture('sleep 240');
$future->resolve();

...and added this snippet to SignalRouter:

$status = getmypid().' got '.$signo."\n";
Filesystem::appendFile('/tmp/signal.log', $status);
echo $status;

Then I ran test.php and signaled it. I saw it TERM the subprocess, which TERM'd the sleep and everything exited properly.

I also ran resist-death.php from libphutil (which ignores signals) with setTimeout() and saw it get TERM'd and then KILL'd a short time later.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T11603, T11592

Differential Revision: https://secure.phabricator.com/D16505