1--TEST--
2mysqli_poll() & references
3--EXTENSIONS--
4mysqli
5--SKIPIF--
6<?php
7require_once 'connect.inc';
8
9if (!$link = @my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
10    die(sprintf("skip Can't connect to MySQL Server - [%d] %s", mysqli_connect_errno(), mysqli_connect_error()));
11
12if (mysqli_get_server_version($link) < 50012)
13    die("skip Test needs SQL function SLEEP() available as of MySQL 5.0.12");
14
15?>
16--FILE--
17<?php
18    require_once 'connect.inc';
19
20    function get_connection() {
21        global $host, $user, $passwd, $db, $port, $socket;
22
23        if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
24            printf("[001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
25        return $link;
26    }
27
28
29    $mysqli1 = get_connection();
30    $mysqli2 = get_connection();
31
32    var_dump(mysqli_query($mysqli1, "SELECT SLEEP(0.10)", MYSQLI_ASYNC | MYSQLI_USE_RESULT));
33    var_dump(mysqli_query($mysqli2, "SELECT SLEEP(0.20)", MYSQLI_ASYNC | MYSQLI_USE_RESULT));
34
35    $processed = $loops = 0;
36    do {
37        $loops++;
38        if ($loops > 10) {
39            printf("[002] The queries should have finished already\n");
40            break;
41        }
42        // WARNING: All arrays point to the same object - this will give bogus results!
43        // The behaviour is in line with stream_select(). Be warned, be careful.
44        $links = $errors = $reject = array($mysqli1, $mysqli2);
45        if (0 == ($ready = mysqli_poll($links, $errors, $reject, 0, 50000))) {
46            continue;
47        }
48
49        foreach ($links as $link) {
50            if ($res = mysqli_reap_async_query($link)) {
51                mysqli_free_result($res);
52            }
53            $processed++;
54        }
55    } while ($processed < 2);
56
57    mysqli_close($mysqli1);
58    mysqli_close($mysqli2);
59
60    $mysqli1 = get_connection();
61    $mysqli2 = get_connection();
62
63    var_dump(mysqli_query($mysqli1, "SELECT SLEEP(0.10)", MYSQLI_ASYNC | MYSQLI_USE_RESULT));
64    var_dump(mysqli_query($mysqli2, "SELECT SLEEP(0.20)", MYSQLI_ASYNC | MYSQLI_USE_RESULT));
65
66    $processed = $loops = 0;
67    do {
68        $loops++;
69        if ($loops > 10) {
70            printf("[003] The queries should have finished already\n");
71            break;
72        }
73        // WARNING: All arrays point to the same object - this will give bogus results!
74        $links = $errors = array($mysqli1, $mysqli2);
75        $reject = array($mysqli1, $mysqli2);
76        if (0 == ($ready = mysqli_poll($links, $errors, $reject, 0, 50000))) {
77            continue;
78        }
79        foreach ($links as $link) {
80            if ($res = mysqli_reap_async_query($link)) {
81                mysqli_free_result($res);
82            }
83            $processed++;
84        }
85    } while ($processed < 2);
86
87    mysqli_close($mysqli1);
88    mysqli_close($mysqli2);
89
90    $mysqli1 = get_connection();
91    $mysqli2 = get_connection();
92
93    var_dump(mysqli_query($mysqli1, "SELECT SLEEP(0.10)", MYSQLI_ASYNC | MYSQLI_USE_RESULT));
94    var_dump(mysqli_query($mysqli2, "SELECT SLEEP(0.20)", MYSQLI_ASYNC | MYSQLI_USE_RESULT));
95
96    $processed = $loops = 0;
97    do {
98        $loops++;
99        if ($loops > 10) {
100            printf("[004] The queries should have finished already\n");
101            break;
102        }
103        // WARNING: All arrays point to the same object - this will give bogus results!
104        $links = array($mysqli1, $mysqli2);
105        $errors = $reject = array($mysqli1, $mysqli2);
106        if (0 == ($ready = mysqli_poll($links, $errors, $reject, 0, 50000))) {
107            continue;
108        }
109        foreach ($links as $link) {
110            if ($res = mysqli_reap_async_query($link)) {
111                mysqli_free_result($res);
112            }
113            $processed++;
114        }
115    } while ($processed < 2);
116
117    mysqli_close($mysqli1);
118    mysqli_close($mysqli2);
119
120    // This is bogus code and bogus usage - OK to throw no errors!
121    $mysqli1 = get_connection();
122    $mysqli2 = get_connection();
123
124    var_dump(mysqli_query($mysqli1, "SELECT SLEEP(0.10)", MYSQLI_ASYNC | MYSQLI_USE_RESULT));
125    $thread_id = mysqli_thread_id($mysqli2);
126    printf("Connection %d should be rejected...\n", $thread_id);
127
128    $processed = $loops = 0;
129    do {
130        $loops++;
131        if ($loops > 10) {
132            printf("[005] The queries should have finished already\n");
133            break;
134        }
135        $links = $errors = $reject = array($mysqli1, $mysqli2);
136        if (0 == ($ready = mysqli_poll($links, $errors, $reject, 0, 50000))) {
137            continue;
138        }
139        // WARNING: Due to the reference issue none of these should ever fire!
140        foreach ($reject as $link) {
141            printf("Connection %d was rejected...\n", mysqli_thread_id($link));
142            if (mysqli_thread_id($link) != $thread_id) {
143                printf("[006] Connector %d should have been rejected. But also %d has been rejected.",
144                  $thread_id, mysqli_thread_id($link));
145            }
146            $processed++;
147        }
148        foreach ($errors as $link) {
149            printf("Connection %d has an error...\n", mysqli_thread_id($link));
150            $processed++;
151        }
152        foreach ($links as $link) {
153            if ($res = mysqli_reap_async_query($link)) {
154                mysqli_free_result($res);
155                $processed++;
156            }
157        }
158    } while ($processed < 2);
159
160    mysqli_close($mysqli1);
161    mysqli_close($mysqli2);
162
163    $mysqli1 = get_connection();
164    $mysqli2 = get_connection();
165
166    var_dump(mysqli_query($mysqli1, "SELECT SLEEP(0.10)", MYSQLI_ASYNC | MYSQLI_USE_RESULT));
167    var_dump(mysqli_query($mysqli2, "SELECT SLEEP(0.20)", MYSQLI_ASYNC | MYSQLI_USE_RESULT));
168
169    $processed = $loops = 0;
170    $all = array($mysqli1, $mysqli2);
171    do {
172        $loops++;
173        if ($loops > 10) {
174            printf("[006] The queries should have finished already\n");
175            break;
176        }
177        $links = $errors = $reject = $all;
178        ob_start();
179        if (0 == ($ready = mysqli_poll($links, $errors, $reject, 0, 50000))) {
180            $tmp = ob_get_contents();
181            ob_end_clean();
182            if ($tmp != '') {
183                printf("Expected error:\n%s\n", $tmp);
184                break;
185            }
186            continue;
187        }
188        foreach ($links as $link) {
189            if ($res = mysqli_reap_async_query($link)) {
190                mysqli_free_result($res);
191            }
192            $processed++;
193        }
194    } while ($processed < 2);
195
196    $ready = mysqli_poll($links, $errors, $reject, 0, 50000);
197    mysqli_close($mysqli1);
198    mysqli_close($mysqli2);
199
200    print "done!";
201?>
202--EXPECTF--
203bool(true)
204bool(true)
205bool(true)
206bool(true)
207bool(true)
208bool(true)
209bool(true)
210Connection %d should be rejected...
211Connection %d was rejected...
212bool(true)
213bool(true)
214
215Warning: mysqli_poll(): All arrays passed are clear in %s on line %d
216done!
217