1<?php
2
3namespace React\Promise;
4
5class CancellationQueue
6{
7    private $started = false;
8    private $queue = [];
9
10    public function __invoke()
11    {
12        if ($this->started) {
13            return;
14        }
15
16        $this->started = true;
17        $this->drain();
18    }
19
20    public function enqueue($cancellable)
21    {
22        if (!\is_object($cancellable) || !\method_exists($cancellable, 'then') || !\method_exists($cancellable, 'cancel')) {
23            return;
24        }
25
26        $length = \array_push($this->queue, $cancellable);
27
28        if ($this->started && 1 === $length) {
29            $this->drain();
30        }
31    }
32
33    private function drain()
34    {
35        for ($i = key($this->queue); isset($this->queue[$i]); $i++) {
36            $cancellable = $this->queue[$i];
37
38            $exception = null;
39
40            try {
41                $cancellable->cancel();
42            } catch (\Throwable $exception) {
43            } catch (\Exception $exception) {
44            }
45
46            unset($this->queue[$i]);
47
48            if ($exception) {
49                throw $exception;
50            }
51        }
52
53        $this->queue = [];
54    }
55}
56