Force children to exit
This commit is contained in:
parent
8d1b772382
commit
d40f5d940a
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,5 +1,5 @@
|
|||||||
/vendor/
|
/vendor/
|
||||||
/composer.lock
|
composer.lock
|
||||||
/.idea/
|
/.idea/
|
||||||
/.phpstorm/
|
/.phpstorm/
|
||||||
/.vscode/
|
/.vscode/
|
@ -14,6 +14,7 @@
|
|||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"ext-pcntl": "*",
|
"ext-pcntl": "*",
|
||||||
"ext-sysvshm": "*"
|
"ext-sysvshm": "*",
|
||||||
|
"ext-posix": "*"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,7 +91,7 @@ class Asynchronous
|
|||||||
*/
|
*/
|
||||||
$instance = self::getInstance();
|
$instance = self::getInstance();
|
||||||
foreach ($instance->children as $index => $pid) {
|
foreach ($instance->children as $index => $pid) {
|
||||||
$response = pcntl_waitpid($pid, $status, WNOHANG);
|
$response = pcntl_waitpid($pid, $status, WNOHANG | WUNTRACED);
|
||||||
if ($response === $pid)
|
if ($response === $pid)
|
||||||
unset($instance->children[$index]);
|
unset($instance->children[$index]);
|
||||||
}
|
}
|
||||||
@ -104,11 +104,39 @@ class Asynchronous
|
|||||||
{
|
{
|
||||||
$instance = self::getInstance();
|
$instance = self::getInstance();
|
||||||
while (count($instance->children) > 0) {
|
while (count($instance->children) > 0) {
|
||||||
pcntl_wait($status);
|
pcntl_wait($status, WUNTRACED);
|
||||||
array_shift($instance->children);
|
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
|
* @return int
|
||||||
*/
|
*/
|
||||||
@ -199,38 +227,26 @@ class Asynchronous
|
|||||||
/*
|
/*
|
||||||
* The shutdown handler
|
* The shutdown handler
|
||||||
*/
|
*/
|
||||||
$handler = function () use (&$instance) {
|
register_shutdown_function(function () use (&$instance) {
|
||||||
/*
|
|
||||||
* A child process has no business here.
|
|
||||||
*/
|
|
||||||
if ($instance->isChild)
|
if ($instance->isChild)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
|
||||||
* Wait for all children to finish to
|
|
||||||
* ensure that all writing to the shared
|
|
||||||
* memory block is finished.
|
|
||||||
*/
|
|
||||||
self::awaitChildren();
|
self::awaitChildren();
|
||||||
|
self::removedShmBlock();
|
||||||
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ask the kernel to mark the shared memory
|
* The signal handler
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Actually register the handler as shutdown
|
|
||||||
* handler and signal handler for SIGINT, SIGTERM
|
|
||||||
*/
|
|
||||||
register_shutdown_function($handler);
|
|
||||||
foreach ([SIGINT, SIGTERM] as $SIGNAL)
|
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();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user