1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

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
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;