1--TEST--
2Fibers in destructors 005: Suspended and not resumed destructor
3--FILE--
4<?php
5
6register_shutdown_function(function () {
7    printf("Shutdown\n");
8});
9
10class Cycle {
11    public $self;
12    public function __construct(public int $id) {
13        $this->self = $this;
14    }
15    public function __destruct() {
16        printf("%d: Start destruct\n", $this->id);
17        try {
18            if ($this->id === 0) {
19                /* Fiber will be collected by GC because it's not referenced */
20                Fiber::suspend(new stdClass);
21            } else if ($this->id === 1) {
22                /* Fiber will be dtor during shutdown */
23                global $f2;
24                $f2 = Fiber::getCurrent();
25                Fiber::suspend(new stdClass);
26            }
27        } finally {
28            printf("%d: End destruct\n", $this->id);
29        }
30    }
31}
32
33$refs = [];
34$f = new Fiber(function () use (&$refs) {
35    $refs[] = WeakReference::create(new Cycle(0));
36    $refs[] = WeakReference::create(new Cycle(1));
37    $refs[] = WeakReference::create(new Cycle(2));
38    gc_collect_cycles();
39});
40
41$f->start();
42
43gc_collect_cycles();
44
45foreach ($refs as $id => $ref) {
46    printf("%d: %s\n", $id, $ref->get() ? 'Live' : 'Collected');
47}
48
49?>
50--EXPECT--
512: Start destruct
522: End destruct
530: Start destruct
540: End destruct
551: Start destruct
560: Collected
571: Live
582: Collected
59Shutdown
601: End destruct
61