/** * Child process signal handler */ public function childSignalHandler($signo, $pid = null, $status = null) { // If no pid is provided, that means we're getting the signal from the system. Let's figure out // which child process ended if ($pid === null) { $pid = pcntl_waitpid(-1, $status, WNOHANG); } //Make sure we get all of the exited children while ($pid > 0) { if ($pid && isset($this->runningOperations[$pid])) { $exitCode = pcntl_wexitstatus($status); if ($exitCode != 0) { Output::instance()->write("Process of operation " . $this->runningOperations[$pid]->hash . " exited with status {$exitCode}"); // this is required as the MySQL connection might be closed anytime by a fork // this method is asynchronous, and might be triggered by any signal // the only way is to use a dedicated DB connection, and close it afterwards $this->closeDatabaseConnection(); $this->runningOperations[$pid]->reset(); $this->closeDatabaseConnection(); } unset($this->runningOperations[$pid]); } elseif ($pid) { $this->signalQueue[$pid] = $status; } $pid = pcntl_waitpid(-1, $status, WNOHANG); } return true; }
#!/usr/bin/env php <?php use mm\Daemon\Daemon; use mm\Daemon\Output; define('DAEMON_MODE', true); include 'config.php'; // check if media target folder is writeable $storageDir = '/media/aggregateshares/'; if (!is_writeable($storageDir)) { echo "{$storageDir} can not be written to. Wrong user maybe ?\n"; die; } $daemon = new Daemon(); if (DAEMON_MODE) { $out = new Output(STDOUT); declare (ticks=1); // Trap signals that we expect to recieve pcntl_signal(SIGCHLD, array($daemon, 'childHandler')); pcntl_signal(SIGUSR1, array($daemon, 'childHandler')); pcntl_signal(SIGALRM, array($daemon, 'childHandler')); $pid = pcntl_fork(); if ($pid < 0) { error_log("unable to fork daemon"); $out->write("ERROR: unable to fork daemon)"); exit(1); } /* If we got a good PID, then we can exit the parent process. */ if ($pid > 0) { // Wait for confirmation from the child via SIGTERM or SIGCHLD, or // for two seconds to elapse (SIGALRM). pause() should not return. */ pcntl_alarm(2);