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.
40 lines
675 B
PHP
40 lines
675 B
PHP
--TEST--
|
|
GH-15108 004: Segfault with delegated generator in suspended fiber
|
|
--FILE--
|
|
<?php
|
|
|
|
function gen1() {
|
|
yield 'foo';
|
|
Fiber::suspend();
|
|
var_dump("not executed");
|
|
};
|
|
|
|
function gen2($gen) {
|
|
yield from $gen;
|
|
var_dump("not executed");
|
|
}
|
|
|
|
$a = gen1();
|
|
/* Both $b and $c have a root marked with IN_FIBER, but only $b is actually
|
|
* running in a fiber (at shutdown) */
|
|
$b = gen2($a);
|
|
$c = gen2($a);
|
|
|
|
$fiber = new Fiber(function () use ($a, $b, $c) {
|
|
var_dump($b->current());
|
|
var_dump($c->current());
|
|
$b->next();
|
|
var_dump("not executed");
|
|
});
|
|
|
|
$ref = $fiber;
|
|
|
|
$fiber->start();
|
|
|
|
?>
|
|
==DONE==
|
|
--EXPECT--
|
|
string(3) "foo"
|
|
string(3) "foo"
|
|
==DONE==
|