mirror of
https://github.com/danog/amp.git
synced 2025-01-22 13:21:16 +01:00
Always use fresh call stack for immediatelies in UvReactor
This commit is contained in:
parent
c1521d6d7c
commit
609cc2ddfe
@ -14,11 +14,13 @@ class UvReactor implements SignalReactor {
|
|||||||
private $stopException;
|
private $stopException;
|
||||||
private $resolution = 1000;
|
private $resolution = 1000;
|
||||||
private $isWindows;
|
private $isWindows;
|
||||||
|
private $immediates = [];
|
||||||
|
|
||||||
private static $MODE_ONCE = 0;
|
private static $MODE_ONCE = 0;
|
||||||
private static $MODE_REPEAT = 1;
|
private static $MODE_REPEAT = 1;
|
||||||
private static $MODE_STREAM = 2;
|
private static $MODE_STREAM = 2;
|
||||||
private static $MODE_SIGNAL = 3;
|
private static $MODE_SIGNAL = 3;
|
||||||
|
private static $MODE_IMMEDIATE = 4;
|
||||||
|
|
||||||
public function __construct($newLoop = false) {
|
public function __construct($newLoop = false) {
|
||||||
$this->loop = $newLoop ? uv_loop_new() : uv_default_loop();
|
$this->loop = $newLoop ? uv_loop_new() : uv_default_loop();
|
||||||
@ -48,8 +50,13 @@ class UvReactor implements SignalReactor {
|
|||||||
if ($onStart) {
|
if ($onStart) {
|
||||||
$this->immediately(function() use ($onStart) { $onStart($this); });
|
$this->immediately(function() use ($onStart) { $onStart($this); });
|
||||||
}
|
}
|
||||||
uv_run($this->loop);
|
|
||||||
$this->isRunning = false;
|
while ($this->isRunning) {
|
||||||
|
if ($this->immediates && !$this->doImmediates()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
uv_run($this->loop, \UV::RUN_NOWAIT | \UV::RUN_ONCE);
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->stopException) {
|
if ($this->stopException) {
|
||||||
$e = $this->stopException;
|
$e = $this->stopException;
|
||||||
@ -58,6 +65,23 @@ class UvReactor implements SignalReactor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function doImmediates() {
|
||||||
|
$immediates = $this->immediates;
|
||||||
|
foreach ($immediates as $watcherId => $callback) {
|
||||||
|
$callback($this);
|
||||||
|
unset(
|
||||||
|
$this->immediates[$watcherId],
|
||||||
|
$this->watchers[$watcherId]
|
||||||
|
);
|
||||||
|
if (!$this->isRunning) {
|
||||||
|
// If a watcher stops the reactor break out of the loop
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->isRunning;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute a single event loop iteration
|
* Execute a single event loop iteration
|
||||||
*
|
*
|
||||||
@ -65,8 +89,16 @@ class UvReactor implements SignalReactor {
|
|||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function tick() {
|
public function tick() {
|
||||||
|
if ($this->isRunning) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$this->isRunning = true;
|
$this->isRunning = true;
|
||||||
uv_run_once($this->loop);
|
|
||||||
|
if (empty($this->immediates) || $this->doImmediates()) {
|
||||||
|
uv_run($this->loop, \UV::RUN_NOWAIT | \UV::RUN_ONCE);
|
||||||
|
}
|
||||||
|
|
||||||
$this->isRunning = false;
|
$this->isRunning = false;
|
||||||
|
|
||||||
if ($this->stopException) {
|
if ($this->stopException) {
|
||||||
@ -83,6 +115,7 @@ class UvReactor implements SignalReactor {
|
|||||||
*/
|
*/
|
||||||
public function stop() {
|
public function stop() {
|
||||||
uv_stop($this->loop);
|
uv_stop($this->loop);
|
||||||
|
$this->isRunning = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -92,7 +125,18 @@ class UvReactor implements SignalReactor {
|
|||||||
* @return int Returns a unique integer watcher ID
|
* @return int Returns a unique integer watcher ID
|
||||||
*/
|
*/
|
||||||
public function immediately(callable $callback) {
|
public function immediately(callable $callback) {
|
||||||
return $this->startTimer($callback, $msDelay = 0, $msInterval = 0, self::$MODE_ONCE);
|
$watcherId = $this->lastWatcherId++;
|
||||||
|
$this->immediates[$watcherId] = $callback;
|
||||||
|
|
||||||
|
$watcher = new \StdClass;
|
||||||
|
$watcher->id = $watcherId;
|
||||||
|
$watcher->mode = self::$MODE_IMMEDIATE;
|
||||||
|
$watcher->callback = $callback;
|
||||||
|
$watcher->isEnabled = true;
|
||||||
|
|
||||||
|
$this->watchers[$watcher->id] = $watcher;
|
||||||
|
|
||||||
|
return $watcherId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -327,6 +371,9 @@ class UvReactor implements SignalReactor {
|
|||||||
case self::$MODE_SIGNAL:
|
case self::$MODE_SIGNAL:
|
||||||
uv_signal_stop($watcher->uvStruct);
|
uv_signal_stop($watcher->uvStruct);
|
||||||
break;
|
break;
|
||||||
|
case self::$MODE_IMMEDIATE:
|
||||||
|
unset($this->immediates[$watcherId]);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
uv_timer_stop($watcher->uvStruct);
|
uv_timer_stop($watcher->uvStruct);
|
||||||
break;
|
break;
|
||||||
@ -365,6 +412,9 @@ class UvReactor implements SignalReactor {
|
|||||||
case self::$MODE_SIGNAL:
|
case self::$MODE_SIGNAL:
|
||||||
uv_signal_stop($watcher->uvStruct);
|
uv_signal_stop($watcher->uvStruct);
|
||||||
break;
|
break;
|
||||||
|
case self::$MODE_IMMEDIATE:
|
||||||
|
unset($this->immediates[$watcher->id]);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
uv_timer_stop($watcher->uvStruct);
|
uv_timer_stop($watcher->uvStruct);
|
||||||
break;
|
break;
|
||||||
@ -397,6 +447,9 @@ class UvReactor implements SignalReactor {
|
|||||||
case self::$MODE_SIGNAL:
|
case self::$MODE_SIGNAL:
|
||||||
uv_signal_start($watcher->uvStruct, $watcher->callback, $watcher->signo);
|
uv_signal_start($watcher->uvStruct, $watcher->callback, $watcher->signo);
|
||||||
break;
|
break;
|
||||||
|
case self::$MODE_IMMEDIATE:
|
||||||
|
$this->immediates[$watcher->id] = $watcher->callback;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
uv_timer_start($watcher->uvStruct, $watcher->msDelay, $watcher->msInterval, $watcher->callback);
|
uv_timer_start($watcher->uvStruct, $watcher->msDelay, $watcher->msInterval, $watcher->callback);
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user