Fix reuse of dtor fiber during shutdown (#16026)

This commit is contained in:
Arnaud Le Blanc 2024-10-02 12:11:10 +02:00 committed by GitHub
parent 341c26fc3f
commit d093c10caf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 73 additions and 0 deletions

View File

@ -0,0 +1,70 @@
--TEST--
Fibers in destructors 011: gc collection after the dtor fiber is dtor
--FILE--
<?php
class SimpleCycle {
public $self;
public function __construct() {
$this->self = $this;
}
public function __destruct() {
printf("%s\n", __METHOD__);
}
}
class CreateGarbageInDtor {
public $self;
public function __construct() {
$this->self = $this;
}
public function __destruct() {
printf("%s\n", __METHOD__);
// Create an object whose dtor will be called after the dtor fiber's
new CollectCyclesInFiberInDtor();
}
}
class CollectCyclesInFiberInDtor {
public $self;
public function __construct() {
$this->self = $this;
}
public function __destruct() {
printf("%s\n", __METHOD__);
new SimpleCycle();
print "Collecting cycles\n";
$f = new Fiber(function () {
gc_collect_cycles();
});
$f->start();
print "Done collecting cycles\n";
}
}
register_shutdown_function(function () {
print "Shutdown\n";
});
// Create a cycle
new SimpleCycle();
// Collect cycles to create the dtor fiber
$f = new Fiber(function () {
gc_collect_cycles();
});
$f->start();
// Create an object whose dtor will be called during shutdown
// (by zend_objects_store_call_destructors)
new CreateGarbageInDtor();
?>
--EXPECT--
SimpleCycle::__destruct
Shutdown
CreateGarbageInDtor::__destruct
CollectCyclesInFiberInDtor::__destruct
Collecting cycles
SimpleCycle::__destruct
Done collecting cycles

View File

@ -2261,6 +2261,9 @@ static ZEND_FUNCTION(gc_destructor_fiber)
if (UNEXPECTED(fiber->flags & ZEND_FIBER_FLAG_DESTROYED)) {
/* Fiber is being destroyed by shutdown sequence */
if (GC_G(dtor_fiber) == fiber) {
GC_G(dtor_fiber) = NULL;
}
GC_DELREF(&fiber->std);
gc_check_possible_root((zend_refcounted*)&fiber->std.gc);
return;