mirror of
https://github.com/php/php-src.git
synced 2024-11-23 01:44:06 +08:00
Fix reuse of dtor fiber during shutdown (#16026)
This commit is contained in:
parent
341c26fc3f
commit
d093c10caf
70
Zend/tests/fibers/destructors_011.phpt
Normal file
70
Zend/tests/fibers/destructors_011.phpt
Normal 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
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user