summaryrefslogtreecommitdiff
path: root/lib/spawningdaemon.php
diff options
context:
space:
mode:
authorBrion Vibber <brion@pobox.com>2010-03-10 11:54:00 -0800
committerBrion Vibber <brion@pobox.com>2010-03-10 11:54:00 -0800
commit532e486a936c78961ff93d5e8de2dc0b86ee8d2a (patch)
treece7dce785643e76df6f9a65d96b1c2ffb95ecf57 /lib/spawningdaemon.php
parent55e8473a7a87ebe85bcfa5cfb409ce9a9aeafdd0 (diff)
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.
Diffstat (limited to 'lib/spawningdaemon.php')
-rw-r--r--lib/spawningdaemon.php32
1 files changed, 32 insertions, 0 deletions
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();
@@ -129,6 +131,34 @@ abstract class SpawningDaemon extends Daemon
}
/**
+ * 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();