diff --git a/src/Forking/Fork.php b/src/Forking/Fork.php index 3bf2ad2..9cd0e24 100644 --- a/src/Forking/Fork.php +++ b/src/Forking/Fork.php @@ -158,14 +158,9 @@ class Fork implements ContextInterface case 0: // Child // @codeCoverageIgnoreStart - // We will have a cloned event loop from the parent after forking. The - // child context by default is synchronous and uses the parent event - // loop, so we need to stop the clone before doing any work in case it - // is already running. - $loop = Loop\loop(); - $loop->stop(); - $loop->reInit(); - $loop->clear(); + // Create a new event loop in the fork. + $loop = Loop\create(false); + Loop\loop($loop); $channel = new Channel(new DuplexStream($parent)); fclose($child); diff --git a/src/Threading/Internal/Thread.php b/src/Threading/Internal/Thread.php index 408047b..ef9a0d1 100644 --- a/src/Threading/Internal/Thread.php +++ b/src/Threading/Internal/Thread.php @@ -17,6 +17,8 @@ use Icicle\Socket\Stream\DuplexStream; */ class Thread extends \Thread { + const KILL_CHECK_FREQUENCY = 0.25; + /** * @var callable The function to execute in the thread. */ @@ -32,6 +34,11 @@ class Thread extends \Thread */ private $socket; + /** + * @var bool + */ + private $killed = false; + /** * 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. $channel = new Channel(new DuplexStream($this->socket)); $coroutine = new Coroutine($this->execute($channel)); $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(); } /** diff --git a/src/Threading/Thread.php b/src/Threading/Thread.php index b57291f..378dfe7 100644 --- a/src/Threading/Thread.php +++ b/src/Threading/Thread.php @@ -138,11 +138,13 @@ class Thread implements ContextInterface */ public function kill() { + if (null === $this->thread) { + throw new StatusError('The thread has not been started.'); + } + $this->close(); - if ($this->isRunning() && !$this->thread->kill()) { - throw new ThreadException('Failed to kill the thread.'); - } + $this->thread->kill(); } /**