Skip to content

Commit

Permalink
Took into account if the loop is still running and if there are any s…
Browse files Browse the repository at this point in the history
…ignal listeners attached for calling `uv_run`, modeled (copied) the bit from `ExtEvLoop` and had to rename $timerEvents to $timers (also makes more sense) as suggested by @clue at reactphp#112 (comment)
  • Loading branch information
WyriHaximus committed Dec 10, 2018
1 parent 8db0f57 commit 2655e98
Showing 1 changed file with 22 additions and 12 deletions.
34 changes: 22 additions & 12 deletions src/ExtUvLoop.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ final class ExtUvLoop implements LoopInterface
{
private $uv;
private $futureTickQueue;
private $timerEvents;
private $timers;
private $streamEvents = array();
private $flags = array();
private $readStreams = array();
Expand All @@ -31,7 +31,7 @@ public function __construct()

$this->uv = \uv_loop_new();
$this->futureTickQueue = new FutureTickQueue();
$this->timerEvents = new SplObjectStorage();
$this->timers = new SplObjectStorage();
$this->streamListener = $this->createStreamListener();
$this->signals = new SignalsHandler();
}
Expand Down Expand Up @@ -96,7 +96,7 @@ public function addTimer($interval, $callback)
$timer = new Timer( $interval, $callback, false);

$that = $this;
$timers = $this->timerEvents;
$timers = $this->timers;
$callback = function () use ($timer, $timers, $that) {
call_user_func($timer->getCallback(), $timer);

Expand All @@ -106,7 +106,7 @@ public function addTimer($interval, $callback)
};

$event = \uv_timer_init($this->uv);
$this->timerEvents->attach($timer, $event);
$this->timers->attach($timer, $event);
\uv_timer_start(
$event,
(int)ceil($interval * 1000),
Expand All @@ -129,7 +129,7 @@ public function addPeriodicTimer($interval, $callback)
};

$event = \uv_timer_init($this->uv);
$this->timerEvents->attach($timer, $event);
$this->timers->attach($timer, $event);
\uv_timer_start(
$event,
(int)ceil($interval * 1000),
Expand All @@ -145,9 +145,9 @@ public function addPeriodicTimer($interval, $callback)
*/
public function cancelTimer(TimerInterface $timer)
{
if (isset($this->timerEvents[$timer])) {
@\uv_timer_stop($this->timerEvents[$timer]);
$this->timerEvents->detach($timer);
if (isset($this->timers[$timer])) {
@\uv_timer_stop($this->timers[$timer]);
$this->timers->detach($timer);
}
}

Expand Down Expand Up @@ -192,14 +192,24 @@ public function run()
while ($this->running) {
$this->futureTickQueue->tick();

if ($this->futureTickQueue->isEmpty() && empty($this->streamEvents) && $this->timerEvents->count() === 0) {
break;
}
$hasPendingCallbacks = !$this->futureTickQueue->isEmpty();
$wasJustStopped = !$this->running;
$nothingLeftToDo = !$this->readStreams
&& !$this->writeStreams
&& !$this->timers->count()
&& $this->signals->isEmpty();

// Use UV::RUN_ONCE when there are only I/O events active in the loop and block until one of those triggers,
// otherwise use UV::RUN_NOWAIT.
// @link http://docs.libuv.org/en/v1.x/loop.html#c.uv_run
\uv_run($this->uv, $this->futureTickQueue->isEmpty() && $this->timerEvents->count() === 0 ? \UV::RUN_ONCE : \UV::RUN_NOWAIT);
$flags = \UV::RUN_ONCE;
if ($wasJustStopped || $hasPendingCallbacks) {
$flags = \UV::RUN_NOWAIT;
} elseif ($nothingLeftToDo) {
break;
}

\uv_run($this->uv, $flags);
}
}

Expand Down

0 comments on commit 2655e98

Please sign in to comment.