2019-08-02 22:09:38 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace Amp;
|
|
|
|
|
|
|
|
final class CombinedCancellationToken implements CancellationToken
|
|
|
|
{
|
2020-03-28 12:23:46 +01:00
|
|
|
/** @var array{0: CancellationToken, 1: string}[] */
|
2019-08-02 22:09:38 +02:00
|
|
|
private $tokens = [];
|
|
|
|
|
2020-03-28 12:23:46 +01:00
|
|
|
/** @var string */
|
2019-08-02 22:09:38 +02:00
|
|
|
private $nextId = "a";
|
2020-03-28 12:23:46 +01:00
|
|
|
|
|
|
|
/** @var callable[] */
|
2019-08-02 22:09:38 +02:00
|
|
|
private $callbacks = [];
|
2020-03-28 12:23:46 +01:00
|
|
|
|
|
|
|
/** @var CancelledException|null */
|
2019-08-02 22:09:38 +02:00
|
|
|
private $exception;
|
|
|
|
|
|
|
|
public function __construct(CancellationToken ...$tokens)
|
|
|
|
{
|
|
|
|
foreach ($tokens as $token) {
|
2020-03-28 12:23:46 +01:00
|
|
|
$id = $token->subscribe(function (CancelledException $exception) {
|
2019-08-02 22:09:38 +02:00
|
|
|
$this->exception = $exception;
|
|
|
|
|
|
|
|
$callbacks = $this->callbacks;
|
|
|
|
$this->callbacks = [];
|
|
|
|
|
|
|
|
foreach ($callbacks as $callback) {
|
|
|
|
asyncCall($callback, $this->exception);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
$this->tokens[] = [$token, $id];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function __destruct()
|
|
|
|
{
|
2019-08-02 22:16:57 +02:00
|
|
|
foreach ($this->tokens as list($token, $id)) {
|
2019-08-02 22:09:38 +02:00
|
|
|
/** @var CancellationToken $token */
|
|
|
|
$token->unsubscribe($id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** @inheritdoc */
|
|
|
|
public function subscribe(callable $callback): string
|
|
|
|
{
|
|
|
|
$id = $this->nextId++;
|
|
|
|
|
|
|
|
if ($this->exception) {
|
|
|
|
asyncCall($callback, $this->exception);
|
|
|
|
} else {
|
|
|
|
$this->callbacks[$id] = $callback;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $id;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** @inheritdoc */
|
2020-09-25 05:17:13 +02:00
|
|
|
public function unsubscribe(string $id): void
|
2019-08-02 22:09:38 +02:00
|
|
|
{
|
|
|
|
unset($this->callbacks[$id]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** @inheritdoc */
|
|
|
|
public function isRequested(): bool
|
|
|
|
{
|
2019-08-02 22:16:57 +02:00
|
|
|
foreach ($this->tokens as list($token)) {
|
2019-08-02 22:09:38 +02:00
|
|
|
if ($token->isRequested()) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** @inheritdoc */
|
2020-09-25 05:17:13 +02:00
|
|
|
public function throwIfRequested(): void
|
2019-08-02 22:09:38 +02:00
|
|
|
{
|
2019-08-02 22:16:57 +02:00
|
|
|
foreach ($this->tokens as list($token)) {
|
2019-08-02 22:09:38 +02:00
|
|
|
$token->throwIfRequested();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|