1--TEST--
2Check for uv_listen callback is not destroyed by gc
3--FILE--
4<?php
5class TcpServer
6{
7    private $loop;
8    private $tcp;
9
10    public function __construct($loop)
11    {
12        $this->loop = $loop;
13        $this->tcp = uv_tcp_init($loop);
14    }
15
16    public function bind(string $address, int $port)
17    {
18        uv_tcp_bind($this->tcp, uv_ip4_addr($address, $port));
19    }
20
21    public function listen()
22    {
23        uv_listen($this->tcp, 100, function ($server, $status) {
24
25            $client = uv_tcp_init($this->loop);
26            uv_accept($server, $client);
27
28            uv_read_start($client, function ($socket, $buffer) {
29                echo 'OK', PHP_EOL;
30                uv_close($socket);
31            });
32        });
33    }
34
35    public function close()
36    {
37        if ($this->tcp instanceof UV) {
38            uv_close($this->tcp);
39        }
40    }
41}
42
43$loop = uv_loop_new();
44
45$tcpServer = new TcpServer($loop);
46$tcpServer->bind('0.0.0.0', 9876);
47$tcpServer->listen();
48
49$closed = 0;
50for ($i = 0; $i < 4; $i++) {
51    $c = uv_tcp_init($loop);
52    uv_tcp_connect($c, uv_ip4_addr('0.0.0.0', 9876), function ($stream, $stat) use (&$closed, $tcpServer) {
53        $closed++;
54        uv_close($stream);
55
56        if ($closed === 4) {
57            $tcpServer->close();
58        }
59    });
60}
61
62uv_run($loop, UV::RUN_DEFAULT);
63
64--EXPECTF--
65OK
66OK
67OK
68OK
69