mirror of
https://github.com/danog/amp.git
synced 2024-12-02 17:37:50 +01:00
6d5e0f5ff7
Avoids creating unnecessary promise objects. delay(0) ticking the loop only once required using delay(x) instead of delay(0) in some tests.
75 lines
1.7 KiB
PHP
75 lines
1.7 KiB
PHP
<?php
|
|
|
|
namespace Amp;
|
|
|
|
final class Signal implements Promise
|
|
{
|
|
private Internal\Placeholder $placeholder;
|
|
|
|
/** @var string[] */
|
|
private array $watchers = [];
|
|
|
|
public function __construct(int $signal, int ...$signals)
|
|
{
|
|
$this->placeholder = $placeholder = new Internal\Placeholder;
|
|
|
|
$signals[] = $signal;
|
|
|
|
$watchers = &$this->watchers;
|
|
$callback = static function (string $id, int $signo) use (&$watchers, $placeholder): void {
|
|
foreach ($watchers as $watcher) {
|
|
Loop::cancel($watcher);
|
|
}
|
|
$watchers = [];
|
|
|
|
$placeholder->resolve($signo);
|
|
};
|
|
|
|
foreach ($signals as $signal) {
|
|
$this->watchers[] = Loop::onSignal($signal, $callback);
|
|
}
|
|
}
|
|
|
|
public function __destruct()
|
|
{
|
|
foreach ($this->watchers as $watcher) {
|
|
Loop::cancel($watcher);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* References the internal watcher in the event loop, keeping the loop running while this promise is pending.
|
|
*
|
|
* @return self
|
|
*/
|
|
public function reference(): self
|
|
{
|
|
foreach ($this->watchers as $watcher) {
|
|
Loop::reference($watcher);
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Unreferences the internal watcher in the event loop, allowing the loop to stop while this promise is pending if
|
|
* no other events are pending in the loop.
|
|
*
|
|
* @return self
|
|
*/
|
|
public function unreference(): self
|
|
{
|
|
foreach ($this->watchers as $watcher) {
|
|
Loop::unreference($watcher);
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/** @inheritDoc */
|
|
public function onResolve(callable $onResolved): void
|
|
{
|
|
$this->placeholder->onResolve($onResolved);
|
|
}
|
|
}
|