Make sure Loop abortJobs does not lose track of promises in case wait() is called within the scope of a wait(), refs #9463

main
Jordi Boggiano 4 years ago
parent b0d308319e
commit 4b4a3937ea
No known key found for this signature in database
GPG Key ID: 7BBD42C429EC80BC

@ -25,8 +25,10 @@ class Loop
private $httpDownloader; private $httpDownloader;
/** @var ProcessExecutor|null */ /** @var ProcessExecutor|null */
private $processExecutor; private $processExecutor;
/** @var Promise[]|null */ /** @var Promise[][] */
private $currentPromises; private $currentPromises = array();
/** @var int */
private $waitIndex = 0;
public function __construct(HttpDownloader $httpDownloader, ProcessExecutor $processExecutor = null) public function __construct(HttpDownloader $httpDownloader, ProcessExecutor $processExecutor = null)
{ {
@ -67,7 +69,10 @@ class Loop
} }
); );
$this->currentPromises = $promises; // keep track of every group of promises that is waited on, so abortJobs can
// cancel them all, even if wait() was called within a wait()
$waitIndex = $this->waitIndex++;
$this->currentPromises[$waitIndex] = $promises;
if ($progress) { if ($progress) {
$totalJobs = 0; $totalJobs = 0;
@ -101,7 +106,7 @@ class Loop
usleep(5000); usleep(5000);
} }
$this->currentPromises = null; unset($this->currentPromises[$waitIndex]);
if ($uncaught) { if ($uncaught) {
throw $uncaught; throw $uncaught;
} }
@ -109,8 +114,8 @@ class Loop
public function abortJobs() public function abortJobs()
{ {
if ($this->currentPromises) { foreach ($this->currentPromises as $promiseGroup) {
foreach ($this->currentPromises as $promise) { foreach ($promiseGroup as $promise) {
$promise->cancel(); $promise->cancel();
} }
} }

Loading…
Cancel
Save