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