mirror of
https://github.com/php/php-src.git
synced 2024-09-21 18:07:23 +00:00
99e0d3fe09
The destructor of generators is a no-op when the generator is running in a fiber, because the fiber may resume the generator. Normally the destructor is not called in this case, but this can happen during shutdown. We detect that a generator is running in a fiber with the ZEND_GENERATOR_IN_FIBER flag. This change fixes two cases not handled by this mechanism: - The ZEND_GENERATOR_IN_FIBER flag was not added when resuming a "yield from $nonGenerator" - When a generator that is running in a fiber has multiple children (aka multiple generators yielding from it), all of them could be considered to also run in a fiber (only one actually is), and could leak if not destroyed before shutdown.
39 lines
570 B
PHP
39 lines
570 B
PHP
--TEST--
|
|
GH-15108 003: Segfault with delegated generator in suspended fiber
|
|
--FILE--
|
|
<?php
|
|
|
|
class It implements \IteratorAggregate
|
|
{
|
|
public function getIterator(): \Generator
|
|
{
|
|
yield 'foo';
|
|
Fiber::suspend();
|
|
var_dump("not executed");
|
|
}
|
|
}
|
|
|
|
function f($gen) {
|
|
yield from $gen;
|
|
}
|
|
|
|
$a = new It();
|
|
$b = f($a);
|
|
$c = f($a);
|
|
|
|
$fiber = new Fiber(function () use ($a, $b, $c) {
|
|
var_dump($b->current());
|
|
$b->next();
|
|
var_dump("not executed");
|
|
});
|
|
|
|
$ref = $fiber;
|
|
|
|
$fiber->start();
|
|
|
|
?>
|
|
==DONE==
|
|
--EXPECT--
|
|
string(3) "foo"
|
|
==DONE==
|