Skip to content

Commit dd063b3

Browse files
committed
Merge branch 'PHP-8.4'
* PHP-8.4: [ci skip] NEWS for GH-16026 Fix reuse of dtor fiber during shutdown (#16026)
2 parents f1b41d7 + 4512a8f commit dd063b3

File tree

2 files changed

+73
-0
lines changed

2 files changed

+73
-0
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
--TEST--
2+
Fibers in destructors 011: gc collection after the dtor fiber is dtor
3+
--FILE--
4+
<?php
5+
6+
class SimpleCycle {
7+
public $self;
8+
public function __construct() {
9+
$this->self = $this;
10+
}
11+
public function __destruct() {
12+
printf("%s\n", __METHOD__);
13+
}
14+
}
15+
16+
class CreateGarbageInDtor {
17+
public $self;
18+
public function __construct() {
19+
$this->self = $this;
20+
}
21+
public function __destruct() {
22+
printf("%s\n", __METHOD__);
23+
// Create an object whose dtor will be called after the dtor fiber's
24+
new CollectCyclesInFiberInDtor();
25+
}
26+
}
27+
28+
class CollectCyclesInFiberInDtor {
29+
public $self;
30+
public function __construct() {
31+
$this->self = $this;
32+
}
33+
public function __destruct() {
34+
printf("%s\n", __METHOD__);
35+
new SimpleCycle();
36+
print "Collecting cycles\n";
37+
$f = new Fiber(function () {
38+
gc_collect_cycles();
39+
});
40+
$f->start();
41+
print "Done collecting cycles\n";
42+
}
43+
}
44+
45+
register_shutdown_function(function () {
46+
print "Shutdown\n";
47+
});
48+
49+
// Create a cycle
50+
new SimpleCycle();
51+
52+
// Collect cycles to create the dtor fiber
53+
$f = new Fiber(function () {
54+
gc_collect_cycles();
55+
});
56+
$f->start();
57+
58+
// Create an object whose dtor will be called during shutdown
59+
// (by zend_objects_store_call_destructors)
60+
new CreateGarbageInDtor();
61+
62+
?>
63+
--EXPECT--
64+
SimpleCycle::__destruct
65+
Shutdown
66+
CreateGarbageInDtor::__destruct
67+
CollectCyclesInFiberInDtor::__destruct
68+
Collecting cycles
69+
SimpleCycle::__destruct
70+
Done collecting cycles

Zend/zend_gc.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2261,6 +2261,9 @@ static ZEND_FUNCTION(gc_destructor_fiber)
22612261

22622262
if (UNEXPECTED(fiber->flags & ZEND_FIBER_FLAG_DESTROYED)) {
22632263
/* Fiber is being destroyed by shutdown sequence */
2264+
if (GC_G(dtor_fiber) == fiber) {
2265+
GC_G(dtor_fiber) = NULL;
2266+
}
22642267
GC_DELREF(&fiber->std);
22652268
gc_check_possible_root((zend_refcounted*)&fiber->std.gc);
22662269
return;

0 commit comments

Comments
 (0)