diff --git a/.gitignore b/.gitignore index 16b9744..cbfa2d6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ /vendor/ -/composer.lock +composer.lock /.idea/ /.phpstorm/ /.vscode/ \ No newline at end of file diff --git a/composer.json b/composer.json index d26845d..7b4e780 100644 --- a/composer.json +++ b/composer.json @@ -14,6 +14,7 @@ }, "require": { "ext-pcntl": "*", - "ext-sysvshm": "*" + "ext-sysvshm": "*", + "ext-posix": "*" } } diff --git a/src/Asynchronous.php b/src/Asynchronous.php index e46efbf..266098f 100644 --- a/src/Asynchronous.php +++ b/src/Asynchronous.php @@ -91,7 +91,7 @@ class Asynchronous */ $instance = self::getInstance(); foreach ($instance->children as $index => $pid) { - $response = pcntl_waitpid($pid, $status, WNOHANG); + $response = pcntl_waitpid($pid, $status, WNOHANG | WUNTRACED); if ($response === $pid) unset($instance->children[$index]); } @@ -104,11 +104,39 @@ class Asynchronous { $instance = self::getInstance(); while (count($instance->children) > 0) { - pcntl_wait($status); + pcntl_wait($status, WUNTRACED); array_shift($instance->children); } } + /** + * Very, very inappropriate name. + */ + public static function killChildren() + { + $instance = self::getInstance(); + + /* + * Require the children to terminate + */ + foreach ($instance->children as $index => $pid) + if (!posix_kill($pid, SIGKILL)) + posix_kill($pid, SIGTERM); + + } + + /** + * + */ + public static function removedShmBlock() + { + $instance = self::getInstance(); + if (is_resource($instance->shm)) { + shm_remove($instance->shm); + shm_detach($instance->shm); + } + } + /** * @return int */ @@ -199,38 +227,26 @@ class Asynchronous /* * The shutdown handler */ - $handler = function () use (&$instance) { - /* - * A child process has no business here. - */ + register_shutdown_function(function () use (&$instance) { if ($instance->isChild) return; - /* - * Wait for all children to finish to - * ensure that all writing to the shared - * memory block is finished. - */ self::awaitChildren(); - - /* - * Ask the kernel to mark the shared memory - * block for removal and detach from it to - * actually allow for removal. - */ - if (is_resource($instance->shm)) { - shm_remove($instance->shm); - shm_detach($instance->shm); - } - }; + self::removedShmBlock(); + }); /* - * Actually register the handler as shutdown - * handler and signal handler for SIGINT, SIGTERM + * The signal handler */ - register_shutdown_function($handler); foreach ([SIGINT, SIGTERM] as $SIGNAL) - pcntl_signal($SIGNAL, $handler); + pcntl_signal($SIGNAL, function () use (&$instance) { + if ($instance->isChild) + return; + + self::killChildren(); + self::awaitChildren(); + self::removedShmBlock(); + }); } } \ No newline at end of file