1
0
mirror of https://github.com/danog/amp.git synced 2024-12-04 18:38:17 +01:00
amp/src/CombinedCancellationToken.php

84 lines
1.9 KiB
PHP
Raw Normal View History

<?php
namespace Amp;
2021-10-15 00:50:40 +02:00
use Revolt\EventLoop;
2021-03-26 22:34:32 +01:00
final class CombinedCancellationToken implements CancellationToken
{
2021-09-04 01:15:31 +02:00
/** @var array<int, array{CancellationToken, string}> */
2020-10-02 20:55:46 +02:00
private array $tokens = [];
2020-10-02 20:55:46 +02:00
private string $nextId = "a";
2021-09-04 01:15:31 +02:00
/** @var callable(CancelledException)[] */
2020-10-02 20:55:46 +02:00
private array $callbacks = [];
2021-09-04 01:15:31 +02:00
private ?CancelledException $exception = null;
public function __construct(CancellationToken ...$tokens)
{
foreach ($tokens as $token) {
2020-10-23 06:03:58 +02:00
$id = $token->subscribe(function (CancelledException $exception): void {
$this->exception = $exception;
$callbacks = $this->callbacks;
$this->callbacks = [];
foreach ($callbacks as $callback) {
2021-10-15 00:50:40 +02:00
EventLoop::queue($callback, $exception);
}
});
$this->tokens[] = [$token, $id];
}
}
public function __destruct()
{
2020-10-25 21:44:01 +01:00
foreach ($this->tokens as [$token, $id]) {
/** @var CancellationToken $token */
$token->unsubscribe($id);
}
}
2021-12-02 18:40:51 +01:00
public function subscribe(\Closure $callback): string
{
$id = $this->nextId++;
2021-09-04 01:15:31 +02:00
if ($this->exception) {
2021-10-15 00:50:40 +02:00
EventLoop::queue($callback, $this->exception);
} else {
$this->callbacks[$id] = $callback;
}
return $id;
}
/** @inheritdoc */
public function unsubscribe(string $id): void
{
unset($this->callbacks[$id]);
}
/** @inheritdoc */
public function isRequested(): bool
{
2020-10-25 21:44:01 +01:00
foreach ($this->tokens as [$token]) {
if ($token->isRequested()) {
return true;
}
}
return false;
}
/** @inheritdoc */
public function throwIfRequested(): void
{
2020-10-25 21:44:01 +01:00
foreach ($this->tokens as [$token]) {
$token->throwIfRequested();
}
}
}