1<?php
2
3namespace GuzzleHttp\Promise;
4
5/**
6 * A task queue that executes tasks in a FIFO order.
7 *
8 * This task queue class is used to settle promises asynchronously and
9 * maintains a constant stack size. You can use the task queue asynchronously
10 * by calling the `run()` function of the global task queue in an event loop.
11 *
12 *     GuzzleHttp\Promise\Utils::queue()->run();
13 */
14class TaskQueue implements TaskQueueInterface
15{
16    private $enableShutdown = true;
17    private $queue = [];
18
19    public function __construct($withShutdown = true)
20    {
21        if ($withShutdown) {
22            register_shutdown_function(function () {
23                if ($this->enableShutdown) {
24                    // Only run the tasks if an E_ERROR didn't occur.
25                    $err = error_get_last();
26                    if (!$err || ($err['type'] ^ E_ERROR)) {
27                        $this->run();
28                    }
29                }
30            });
31        }
32    }
33
34    public function isEmpty()
35    {
36        return !$this->queue;
37    }
38
39    public function add(callable $task)
40    {
41        $this->queue[] = $task;
42    }
43
44    public function run()
45    {
46        while ($task = array_shift($this->queue)) {
47            /** @var callable $task */
48            $task();
49        }
50    }
51
52    /**
53     * The task queue will be run and exhausted by default when the process
54     * exits IFF the exit is not the result of a PHP E_ERROR error.
55     *
56     * You can disable running the automatic shutdown of the queue by calling
57     * this function. If you disable the task queue shutdown process, then you
58     * MUST either run the task queue (as a result of running your event loop
59     * or manually using the run() method) or wait on each outstanding promise.
60     *
61     * Note: This shutdown will occur before any destructors are triggered.
62     */
63    public function disableShutdown()
64    {
65        $this->enableShutdown = false;
66    }
67}
68