Add tests for destructors behaviour with GC

This commit is contained in:
Michael Voříšek 2024-03-09 13:28:11 +01:00 committed by Arnaud Le Blanc
parent 2d6bd1644d
commit a470110ff4
3 changed files with 163 additions and 0 deletions

58
Zend/tests/gc_048.phpt Normal file
View File

@ -0,0 +1,58 @@
--TEST--
GC 048: Objects with destructor are collected without delay
--FILE--
<?php
class CycleWithoutDestructor
{
private \stdClass $cycleRef;
public function __construct()
{
$this->cycleRef = new \stdClass();
$this->cycleRef->x = $this;
}
}
class CycleWithDestructor extends CycleWithoutDestructor
{
public function __construct()
{
parent::__construct();
}
public function __destruct()
{
new CycleWithoutDestructor();
}
}
echo "---\n";
$cycleWithoutDestructor = new CycleWithoutDestructor();
$cycleWithoutDestructorWeak = \WeakReference::create($cycleWithoutDestructor);
$cycleWithDestructor = new CycleWithDestructor();
$cycleWithDestructorWeak = \WeakReference::create($cycleWithDestructor);
gc_collect_cycles();
echo "---\n";
unset($cycleWithoutDestructor);
var_dump($cycleWithoutDestructorWeak->get() !== null);
gc_collect_cycles();
var_dump($cycleWithoutDestructorWeak->get() !== null);
echo "---\n";
unset($cycleWithDestructor);
var_dump($cycleWithDestructorWeak->get() !== null);
gc_collect_cycles();
var_dump($cycleWithDestructorWeak->get() !== null);
--EXPECT--
---
---
bool(true)
bool(false)
---
bool(true)
bool(false)

68
Zend/tests/gc_049.phpt Normal file
View File

@ -0,0 +1,68 @@
--TEST--
GC 049: Objects created during GC do not participate in the same collection
--FILE--
<?php
class CycleWithDestructor
{
private \Closure $destructorFx;
private \stdClass $cycleRef;
public function __construct(\Closure $destructorFx)
{
$this->destructorFx = $destructorFx;
$this->cycleRef = new \stdClass();
$this->cycleRef->x = $this;
}
public function __destruct()
{
($this->destructorFx)();
}
}
$isSecondGcRerun = false; // https://github.com/php/php-src/commit/b58d74547f
$createFx = static function () use (&$createFx, &$isSecondGcRerun): void {
$destructorFx = static function () use (&$createFx, &$isSecondGcRerun): void {
if (!gc_status()['running']) {
echo "gc shutdown\n";
return;
}
echo "gc" . ($isSecondGcRerun ? ' rerun' : '') . "\n";
$isSecondGcRerun = !$isSecondGcRerun;
$createFx();
};
new CycleWithDestructor($destructorFx);
};
$createFx();
gc_collect_cycles();
gc_collect_cycles();
gc_collect_cycles();
echo "---\n";
gc_collect_cycles();
gc_collect_cycles();
gc_collect_cycles();
echo "---\n";
?>
--EXPECT--
gc
gc rerun
gc
gc rerun
gc
gc rerun
---
gc
gc rerun
gc
gc rerun
gc
gc rerun
---
gc shutdown

37
Zend/tests/gc_050.phpt Normal file
View File

@ -0,0 +1,37 @@
--TEST--
GC 050: Destructor are never called twice
--FILE--
<?php
class G
{
public static $v;
}
class WithDestructor
{
public function __destruct()
{
echo "d\n";
G::$v = $this;
}
}
$o = new WithDestructor();
$weakO = \WeakReference::create($o);
echo "---\n";
unset($o);
echo "---\n";
var_dump($weakO->get() !== null); // verify if kept allocated
G::$v = null;
echo "---\n";
var_dump($weakO->get() !== null); // verify if released
?>
--EXPECT--
---
d
---
bool(true)
---
bool(false)