mirror of
https://github.com/danog/parallel.git
synced 2024-11-27 04:44:56 +01:00
Fix killing a thread; avoid issues with signals
This commit is contained in:
parent
3f097bab4c
commit
b163207cea
@ -158,14 +158,9 @@ class Fork implements ContextInterface
|
|||||||
case 0: // Child
|
case 0: // Child
|
||||||
// @codeCoverageIgnoreStart
|
// @codeCoverageIgnoreStart
|
||||||
|
|
||||||
// We will have a cloned event loop from the parent after forking. The
|
// Create a new event loop in the fork.
|
||||||
// child context by default is synchronous and uses the parent event
|
$loop = Loop\create(false);
|
||||||
// loop, so we need to stop the clone before doing any work in case it
|
Loop\loop($loop);
|
||||||
// is already running.
|
|
||||||
$loop = Loop\loop();
|
|
||||||
$loop->stop();
|
|
||||||
$loop->reInit();
|
|
||||||
$loop->clear();
|
|
||||||
|
|
||||||
$channel = new Channel(new DuplexStream($parent));
|
$channel = new Channel(new DuplexStream($parent));
|
||||||
fclose($child);
|
fclose($child);
|
||||||
|
@ -17,6 +17,8 @@ use Icicle\Socket\Stream\DuplexStream;
|
|||||||
*/
|
*/
|
||||||
class Thread extends \Thread
|
class Thread extends \Thread
|
||||||
{
|
{
|
||||||
|
const KILL_CHECK_FREQUENCY = 0.25;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var callable The function to execute in the thread.
|
* @var callable The function to execute in the thread.
|
||||||
*/
|
*/
|
||||||
@ -32,6 +34,11 @@ class Thread extends \Thread
|
|||||||
*/
|
*/
|
||||||
private $socket;
|
private $socket;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
private $killed = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new thread object.
|
* Creates a new thread object.
|
||||||
*
|
*
|
||||||
@ -67,13 +74,32 @@ class Thread extends \Thread
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$loop = Loop\create(false); // Disable signals in thread.
|
||||||
|
Loop\loop($loop);
|
||||||
|
|
||||||
// At this point, the thread environment has been prepared so begin using the thread.
|
// At this point, the thread environment has been prepared so begin using the thread.
|
||||||
$channel = new Channel(new DuplexStream($this->socket));
|
$channel = new Channel(new DuplexStream($this->socket));
|
||||||
|
|
||||||
$coroutine = new Coroutine($this->execute($channel));
|
$coroutine = new Coroutine($this->execute($channel));
|
||||||
$coroutine->done();
|
$coroutine->done();
|
||||||
|
|
||||||
Loop\run();
|
$timer = $loop->timer(self::KILL_CHECK_FREQUENCY, true, function () use ($loop, $coroutine, $channel) {
|
||||||
|
if ($this->killed) {
|
||||||
|
$loop->stop();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$timer->unreference();
|
||||||
|
|
||||||
|
$loop->run();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a local variable to true so the running event loop can check for a kill signal.
|
||||||
|
*/
|
||||||
|
public function kill()
|
||||||
|
{
|
||||||
|
$this->killed = true;
|
||||||
|
parent::kill();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -138,11 +138,13 @@ class Thread implements ContextInterface
|
|||||||
*/
|
*/
|
||||||
public function kill()
|
public function kill()
|
||||||
{
|
{
|
||||||
|
if (null === $this->thread) {
|
||||||
|
throw new StatusError('The thread has not been started.');
|
||||||
|
}
|
||||||
|
|
||||||
$this->close();
|
$this->close();
|
||||||
|
|
||||||
if ($this->isRunning() && !$this->thread->kill()) {
|
$this->thread->kill();
|
||||||
throw new ThreadException('Failed to kill the thread.');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user