From 532e486a936c78961ff93d5e8de2dc0b86ee8d2a Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Wed, 10 Mar 2010 11:54:00 -0800 Subject: Detect when queuedaemon/xmppdaemon parent processes die and kill the child processes. Keeps stray daemon subprocesses from floating around when we kill the parents via a signal! Accomplished by opening a bidirectional pipe in the parent process; the children close out the writer end and keep the reader in their open sockets list. When the parent dies, the children see that the socket's been closed out and can perform an orderly shutdown. --- lib/spawningdaemon.php | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'lib/spawningdaemon.php') diff --git a/lib/spawningdaemon.php b/lib/spawningdaemon.php index fd9ae4355..2f9f6e32e 100644 --- a/lib/spawningdaemon.php +++ b/lib/spawningdaemon.php @@ -71,6 +71,8 @@ abstract class SpawningDaemon extends Daemon */ function run() { + $this->initPipes(); + $children = array(); for ($i = 1; $i <= $this->threads; $i++) { $pid = pcntl_fork(); @@ -128,6 +130,34 @@ abstract class SpawningDaemon extends Daemon return true; } + /** + * Create an IPC socket pair which child processes can use to detect + * if the parent process has been killed. + */ + function initPipes() + { + $sockets = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, 0); + if ($sockets) { + $this->parentWriter = $sockets[0]; + $this->parentReader = $sockets[1]; + } else { + $this->log(LOG_ERROR, "Couldn't create inter-process sockets"); + exit(1); + } + } + + /** + * Build an IOManager that simply ensures that we have a connection + * to the parent process open. If it breaks, the child process will + * die. + * + * @return ProcessManager + */ + public function processManager() + { + return new ProcessManager($this->parentReader); + } + /** * Determine whether to respawn an exited subprocess based on its exit code. * Otherwise we'll respawn all exits by default. @@ -152,6 +182,8 @@ abstract class SpawningDaemon extends Daemon */ protected function initAndRunChild($thread) { + // Close the writer end of our parent<->children pipe. + fclose($this->parentWriter); $this->set_id($this->get_id() . "." . $thread); $this->resetDb(); $exitCode = $this->runThread(); -- cgit v1.2.3-54-g00ecf