Skip to content

Commit a470110

Browse files
mvorisekarnaud-lb
authored andcommitted
Add tests for destructors behaviour with GC
1 parent 2d6bd16 commit a470110

File tree

3 files changed

+163
-0
lines changed

3 files changed

+163
-0
lines changed

Zend/tests/gc_048.phpt

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
--TEST--
2+
GC 048: Objects with destructor are collected without delay
3+
--FILE--
4+
<?php
5+
6+
class CycleWithoutDestructor
7+
{
8+
private \stdClass $cycleRef;
9+
10+
public function __construct()
11+
{
12+
$this->cycleRef = new \stdClass();
13+
$this->cycleRef->x = $this;
14+
}
15+
}
16+
17+
class CycleWithDestructor extends CycleWithoutDestructor
18+
{
19+
public function __construct()
20+
{
21+
parent::__construct();
22+
}
23+
24+
public function __destruct()
25+
{
26+
new CycleWithoutDestructor();
27+
}
28+
}
29+
30+
echo "---\n";
31+
32+
$cycleWithoutDestructor = new CycleWithoutDestructor();
33+
$cycleWithoutDestructorWeak = \WeakReference::create($cycleWithoutDestructor);
34+
$cycleWithDestructor = new CycleWithDestructor();
35+
$cycleWithDestructorWeak = \WeakReference::create($cycleWithDestructor);
36+
gc_collect_cycles();
37+
38+
echo "---\n";
39+
40+
unset($cycleWithoutDestructor);
41+
var_dump($cycleWithoutDestructorWeak->get() !== null);
42+
gc_collect_cycles();
43+
var_dump($cycleWithoutDestructorWeak->get() !== null);
44+
45+
echo "---\n";
46+
47+
unset($cycleWithDestructor);
48+
var_dump($cycleWithDestructorWeak->get() !== null);
49+
gc_collect_cycles();
50+
var_dump($cycleWithDestructorWeak->get() !== null);
51+
--EXPECT--
52+
---
53+
---
54+
bool(true)
55+
bool(false)
56+
---
57+
bool(true)
58+
bool(false)

Zend/tests/gc_049.phpt

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
--TEST--
2+
GC 049: Objects created during GC do not participate in the same collection
3+
--FILE--
4+
<?php
5+
6+
class CycleWithDestructor
7+
{
8+
private \Closure $destructorFx;
9+
10+
private \stdClass $cycleRef;
11+
12+
public function __construct(\Closure $destructorFx)
13+
{
14+
$this->destructorFx = $destructorFx;
15+
$this->cycleRef = new \stdClass();
16+
$this->cycleRef->x = $this;
17+
}
18+
19+
public function __destruct()
20+
{
21+
($this->destructorFx)();
22+
}
23+
}
24+
25+
$isSecondGcRerun = false; // https://github.com/php/php-src/commit/b58d74547f
26+
$createFx = static function () use (&$createFx, &$isSecondGcRerun): void {
27+
$destructorFx = static function () use (&$createFx, &$isSecondGcRerun): void {
28+
if (!gc_status()['running']) {
29+
echo "gc shutdown\n";
30+
return;
31+
}
32+
33+
echo "gc" . ($isSecondGcRerun ? ' rerun' : '') . "\n";
34+
35+
$isSecondGcRerun = !$isSecondGcRerun;
36+
37+
$createFx();
38+
};
39+
40+
new CycleWithDestructor($destructorFx);
41+
};
42+
43+
$createFx();
44+
gc_collect_cycles();
45+
gc_collect_cycles();
46+
gc_collect_cycles();
47+
echo "---\n";
48+
gc_collect_cycles();
49+
gc_collect_cycles();
50+
gc_collect_cycles();
51+
echo "---\n";
52+
?>
53+
--EXPECT--
54+
gc
55+
gc rerun
56+
gc
57+
gc rerun
58+
gc
59+
gc rerun
60+
---
61+
gc
62+
gc rerun
63+
gc
64+
gc rerun
65+
gc
66+
gc rerun
67+
---
68+
gc shutdown

Zend/tests/gc_050.phpt

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
--TEST--
2+
GC 050: Destructor are never called twice
3+
--FILE--
4+
<?php
5+
6+
class G
7+
{
8+
public static $v;
9+
}
10+
11+
class WithDestructor
12+
{
13+
public function __destruct()
14+
{
15+
echo "d\n";
16+
17+
G::$v = $this;
18+
}
19+
}
20+
21+
$o = new WithDestructor();
22+
$weakO = \WeakReference::create($o);
23+
echo "---\n";
24+
unset($o);
25+
echo "---\n";
26+
var_dump($weakO->get() !== null); // verify if kept allocated
27+
G::$v = null;
28+
echo "---\n";
29+
var_dump($weakO->get() !== null); // verify if released
30+
?>
31+
--EXPECT--
32+
---
33+
d
34+
---
35+
bool(true)
36+
---
37+
bool(false)

0 commit comments

Comments
 (0)