1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "testutil.h"
18 #include "apr_strings.h"
19 #include "apr_errno.h"
20 #include "apr_general.h"
21 #include "apr_lib.h"
22 #include "apr_network_io.h"
23 #include "apr_poll.h"
24
25 #define SMALL_NUM_SOCKETS 3
26 /* We can't use 64 here, because some platforms *ahem* Solaris *ahem* have
27 * a default limit of 64 open file descriptors per process. If we use
28 * 64, the test will fail even though the code is correct.
29 */
30 #define LARGE_NUM_SOCKETS 50
31
32 static apr_socket_t *s[LARGE_NUM_SOCKETS];
33 static apr_sockaddr_t *sa[LARGE_NUM_SOCKETS];
34 static apr_pollset_t *pollset;
35 static apr_pollcb_t *pollcb;
36
37 /* ###: tests surrounded by ifdef OLD_POLL_INTERFACE either need to be
38 * converted to use the pollset interface or removed. */
39
40 #ifdef OLD_POLL_INTERFACE
41 static apr_pollfd_t *pollarray;
42 static apr_pollfd_t *pollarray_large;
43 #endif
44
45 /* default_pollset_impl can be overridden temporarily to control
46 * testcases which don't specify an implementation explicitly
47 */
48 static int default_pollset_impl = APR_POLLSET_DEFAULT;
49
make_socket(apr_socket_t ** sock,apr_sockaddr_t ** sa,apr_port_t port,apr_pool_t * p,abts_case * tc)50 static void make_socket(apr_socket_t **sock, apr_sockaddr_t **sa,
51 apr_port_t port, apr_pool_t *p, abts_case *tc)
52 {
53 apr_status_t rv;
54
55 rv = apr_sockaddr_info_get(sa, "127.0.0.1", APR_UNSPEC, port, 0, p);
56 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
57
58 rv = apr_socket_create(sock, (*sa)->family, SOCK_DGRAM, 0, p);
59 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
60
61 rv = apr_socket_bind((*sock), (*sa));
62 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
63 }
64
65 #ifdef OLD_POLL_INTERFACE
check_sockets(const apr_pollfd_t * pollarray,apr_socket_t ** sockarray,int which,int pollin,abts_case * tc)66 static void check_sockets(const apr_pollfd_t *pollarray,
67 apr_socket_t **sockarray, int which, int pollin,
68 abts_case *tc)
69 {
70 apr_status_t rv;
71 apr_int16_t event;
72 char *str;
73
74 rv = apr_poll_revents_get(&event, sockarray[which],
75 (apr_pollfd_t *)pollarray);
76 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
77 if (pollin) {
78 str = apr_psprintf(p, "Socket %d not signalled when it should be",
79 which);
80 ABTS_ASSERT(tc, str, event & APR_POLLIN);
81 } else {
82 str = apr_psprintf(p, "Socket %d signalled when it should not be",
83 which);
84 ABTS_ASSERT(tc, str, !(event & APR_POLLIN));
85 }
86 }
87 #endif
88
send_msg(apr_socket_t ** sockarray,apr_sockaddr_t ** sas,int which,abts_case * tc)89 static void send_msg(apr_socket_t **sockarray, apr_sockaddr_t **sas, int which,
90 abts_case *tc)
91 {
92 apr_size_t len = 5;
93 apr_status_t rv;
94
95 ABTS_PTR_NOTNULL(tc, sockarray[which]);
96
97 rv = apr_socket_sendto(sockarray[which], sas[which], 0, "hello", &len);
98 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
99 ABTS_SIZE_EQUAL(tc, strlen("hello"), len);
100 }
101
recv_msg(apr_socket_t ** sockarray,int which,apr_pool_t * p,abts_case * tc)102 static void recv_msg(apr_socket_t **sockarray, int which, apr_pool_t *p,
103 abts_case *tc)
104 {
105 apr_size_t buflen = 5;
106 char *buffer = apr_pcalloc(p, sizeof(char) * (buflen + 1));
107 apr_sockaddr_t *recsa;
108 apr_status_t rv;
109
110 ABTS_PTR_NOTNULL(tc, sockarray[which]);
111
112 apr_sockaddr_info_get(&recsa, "127.0.0.1", APR_UNSPEC, 7770, 0, p);
113
114 rv = apr_socket_recvfrom(recsa, sockarray[which], 0, buffer, &buflen);
115 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
116 ABTS_SIZE_EQUAL(tc, strlen("hello"), buflen);
117 ABTS_STR_EQUAL(tc, "hello", buffer);
118 }
119
120
create_all_sockets(abts_case * tc,void * data)121 static void create_all_sockets(abts_case *tc, void *data)
122 {
123 int i;
124
125 for (i = 0; i < LARGE_NUM_SOCKETS; i++){
126 make_socket(&s[i], &sa[i], 7777 + i, p, tc);
127 }
128 }
129
130 #ifdef OLD_POLL_INTERFACE
setup_small_poll(abts_case * tc,void * data)131 static void setup_small_poll(abts_case *tc, void *data)
132 {
133 apr_status_t rv;
134 int i;
135
136 rv = apr_poll_setup(&pollarray, SMALL_NUM_SOCKETS, p);
137 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
138
139 for (i = 0; i < SMALL_NUM_SOCKETS;i++){
140 ABTS_INT_EQUAL(tc, 0, pollarray[i].reqevents);
141 ABTS_INT_EQUAL(tc, 0, pollarray[i].rtnevents);
142
143 rv = apr_poll_socket_add(pollarray, s[i], APR_POLLIN);
144 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
145 ABTS_PTR_EQUAL(tc, s[i], pollarray[i].desc.s);
146 }
147 }
148
setup_large_poll(abts_case * tc,void * data)149 static void setup_large_poll(abts_case *tc, void *data)
150 {
151 apr_status_t rv;
152 int i;
153
154 rv = apr_poll_setup(&pollarray_large, LARGE_NUM_SOCKETS, p);
155 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
156
157 for (i = 0; i < LARGE_NUM_SOCKETS;i++){
158 ABTS_INT_EQUAL(tc, 0, pollarray_large[i].reqevents);
159 ABTS_INT_EQUAL(tc, 0, pollarray_large[i].rtnevents);
160
161 rv = apr_poll_socket_add(pollarray_large, s[i], APR_POLLIN);
162 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
163 ABTS_PTR_EQUAL(tc, s[i], pollarray_large[i].desc.s);
164 }
165 }
166
nomessage(abts_case * tc,void * data)167 static void nomessage(abts_case *tc, void *data)
168 {
169 apr_status_t rv;
170 int srv = SMALL_NUM_SOCKETS;
171
172 rv = apr_poll(pollarray, SMALL_NUM_SOCKETS, &srv, 2 * APR_USEC_PER_SEC);
173 ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_TIMEUP(rv));
174 check_sockets(pollarray, s, 0, 0, tc);
175 check_sockets(pollarray, s, 1, 0, tc);
176 check_sockets(pollarray, s, 2, 0, tc);
177 }
178
send_2(abts_case * tc,void * data)179 static void send_2(abts_case *tc, void *data)
180 {
181 apr_status_t rv;
182 int srv = SMALL_NUM_SOCKETS;
183
184 send_msg(s, sa, 2, tc);
185
186 rv = apr_poll(pollarray, SMALL_NUM_SOCKETS, &srv, 2 * APR_USEC_PER_SEC);
187 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
188 check_sockets(pollarray, s, 0, 0, tc);
189 check_sockets(pollarray, s, 1, 0, tc);
190 check_sockets(pollarray, s, 2, 1, tc);
191 }
192
recv_2_send_1(abts_case * tc,void * data)193 static void recv_2_send_1(abts_case *tc, void *data)
194 {
195 apr_status_t rv;
196 int srv = SMALL_NUM_SOCKETS;
197
198 recv_msg(s, 2, p, tc);
199 send_msg(s, sa, 1, tc);
200
201 rv = apr_poll(pollarray, SMALL_NUM_SOCKETS, &srv, 2 * APR_USEC_PER_SEC);
202 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
203 check_sockets(pollarray, s, 0, 0, tc);
204 check_sockets(pollarray, s, 1, 1, tc);
205 check_sockets(pollarray, s, 2, 0, tc);
206 }
207
send_2_signaled_1(abts_case * tc,void * data)208 static void send_2_signaled_1(abts_case *tc, void *data)
209 {
210 apr_status_t rv;
211 int srv = SMALL_NUM_SOCKETS;
212
213 send_msg(s, sa, 2, tc);
214
215 rv = apr_poll(pollarray, SMALL_NUM_SOCKETS, &srv, 2 * APR_USEC_PER_SEC);
216 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
217 check_sockets(pollarray, s, 0, 0, tc);
218 check_sockets(pollarray, s, 1, 1, tc);
219 check_sockets(pollarray, s, 2, 1, tc);
220 }
221
recv_1_send_0(abts_case * tc,void * data)222 static void recv_1_send_0(abts_case *tc, void *data)
223 {
224 apr_status_t rv;
225 int srv = SMALL_NUM_SOCKETS;
226
227 recv_msg(s, 1, p, tc);
228 send_msg(s, sa, 0, tc);
229
230 rv = apr_poll(pollarray, SMALL_NUM_SOCKETS, &srv, 2 * APR_USEC_PER_SEC);
231 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
232 check_sockets(pollarray, s, 0, 1, tc);
233 check_sockets(pollarray, s, 1, 0, tc);
234 check_sockets(pollarray, s, 2, 1, tc);
235 }
236
clear_all_signalled(abts_case * tc,void * data)237 static void clear_all_signalled(abts_case *tc, void *data)
238 {
239 apr_status_t rv;
240 int srv = SMALL_NUM_SOCKETS;
241
242 recv_msg(s, 0, p, tc);
243 recv_msg(s, 2, p, tc);
244
245 rv = apr_poll(pollarray, SMALL_NUM_SOCKETS, &srv, 2 * APR_USEC_PER_SEC);
246 ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_TIMEUP(rv));
247 check_sockets(pollarray, s, 0, 0, tc);
248 check_sockets(pollarray, s, 1, 0, tc);
249 check_sockets(pollarray, s, 2, 0, tc);
250 }
251
send_large_pollarray(abts_case * tc,void * data)252 static void send_large_pollarray(abts_case *tc, void *data)
253 {
254 apr_status_t rv;
255 int lrv = LARGE_NUM_SOCKETS;
256 int i;
257
258 send_msg(s, sa, LARGE_NUM_SOCKETS - 1, tc);
259
260 rv = apr_poll(pollarray_large, LARGE_NUM_SOCKETS, &lrv,
261 2 * APR_USEC_PER_SEC);
262 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
263
264 for (i = 0; i < LARGE_NUM_SOCKETS; i++) {
265 if (i == (LARGE_NUM_SOCKETS - 1)) {
266 check_sockets(pollarray_large, s, i, 1, tc);
267 }
268 else {
269 check_sockets(pollarray_large, s, i, 0, tc);
270 }
271 }
272 }
273
recv_large_pollarray(abts_case * tc,void * data)274 static void recv_large_pollarray(abts_case *tc, void *data)
275 {
276 apr_status_t rv;
277 int lrv = LARGE_NUM_SOCKETS;
278 int i;
279
280 recv_msg(s, LARGE_NUM_SOCKETS - 1, p, tc);
281
282 rv = apr_poll(pollarray_large, LARGE_NUM_SOCKETS, &lrv,
283 2 * APR_USEC_PER_SEC);
284 ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_TIMEUP(rv));
285
286 for (i = 0; i < LARGE_NUM_SOCKETS; i++) {
287 check_sockets(pollarray_large, s, i, 0, tc);
288 }
289 }
290 #endif
291
setup_pollset(abts_case * tc,void * data)292 static void setup_pollset(abts_case *tc, void *data)
293 {
294 apr_status_t rv;
295 rv = apr_pollset_create_ex(&pollset, LARGE_NUM_SOCKETS, p, 0,
296 default_pollset_impl);
297 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
298 }
299
multi_event_pollset(abts_case * tc,void * data)300 static void multi_event_pollset(abts_case *tc, void *data)
301 {
302 apr_status_t rv;
303 apr_pollfd_t socket_pollfd;
304 int lrv;
305 const apr_pollfd_t *descs = NULL;
306
307 ABTS_PTR_NOTNULL(tc, s[0]);
308 socket_pollfd.desc_type = APR_POLL_SOCKET;
309 socket_pollfd.reqevents = APR_POLLIN | APR_POLLOUT;
310 socket_pollfd.desc.s = s[0];
311 socket_pollfd.client_data = s[0];
312 rv = apr_pollset_add(pollset, &socket_pollfd);
313 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
314
315 send_msg(s, sa, 0, tc);
316
317 rv = apr_pollset_poll(pollset, -1, &lrv, &descs);
318 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
319 if (lrv == 1) {
320 int ev = descs[0].rtnevents;
321 ABTS_PTR_EQUAL(tc, s[0], descs[0].desc.s);
322 ABTS_PTR_EQUAL(tc, s[0], descs[0].client_data);
323 ABTS_ASSERT(tc, "either or both of APR_POLLIN, APR_POLLOUT returned",
324 ((ev & APR_POLLIN) != 0) || ((ev & APR_POLLOUT) != 0));
325 }
326 else if (lrv == 2) {
327 ABTS_PTR_EQUAL(tc, s[0], descs[0].desc.s);
328 ABTS_PTR_EQUAL(tc, s[0], descs[0].client_data);
329 ABTS_PTR_EQUAL(tc, s[0], descs[1].desc.s);
330 ABTS_PTR_EQUAL(tc, s[0], descs[1].client_data);
331 ABTS_ASSERT(tc, "returned events incorrect",
332 ((descs[0].rtnevents | descs[1].rtnevents)
333 == (APR_POLLIN | APR_POLLOUT))
334 && descs[0].rtnevents != descs[1].rtnevents);
335 }
336 else {
337 ABTS_ASSERT(tc, "either one or two events returned",
338 lrv == 1 || lrv == 2);
339 }
340
341 recv_msg(s, 0, p, tc);
342
343 rv = apr_pollset_poll(pollset, 0, &lrv, &descs);
344 ABTS_INT_EQUAL(tc, 0, APR_STATUS_IS_TIMEUP(rv));
345 ABTS_INT_EQUAL(tc, 1, lrv);
346 ABTS_PTR_EQUAL(tc, s[0], descs[0].desc.s);
347 ABTS_INT_EQUAL(tc, APR_POLLOUT, descs[0].rtnevents);
348 ABTS_PTR_EQUAL(tc, s[0], descs[0].client_data);
349
350 rv = apr_pollset_remove(pollset, &socket_pollfd);
351 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
352 }
353
add_sockets_pollset(abts_case * tc,void * data)354 static void add_sockets_pollset(abts_case *tc, void *data)
355 {
356 apr_status_t rv;
357 int i;
358
359 for (i = 0; i < LARGE_NUM_SOCKETS;i++){
360 apr_pollfd_t socket_pollfd;
361
362 ABTS_PTR_NOTNULL(tc, s[i]);
363
364 socket_pollfd.desc_type = APR_POLL_SOCKET;
365 socket_pollfd.reqevents = APR_POLLIN;
366 socket_pollfd.desc.s = s[i];
367 socket_pollfd.client_data = s[i];
368 rv = apr_pollset_add(pollset, &socket_pollfd);
369 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
370 }
371 }
372
nomessage_pollset(abts_case * tc,void * data)373 static void nomessage_pollset(abts_case *tc, void *data)
374 {
375 apr_status_t rv;
376 int lrv;
377 const apr_pollfd_t *descs = NULL;
378
379 rv = apr_pollset_poll(pollset, 0, &lrv, &descs);
380 ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_TIMEUP(rv));
381 ABTS_INT_EQUAL(tc, 0, lrv);
382 ABTS_PTR_EQUAL(tc, NULL, descs);
383 }
384
send0_pollset(abts_case * tc,void * data)385 static void send0_pollset(abts_case *tc, void *data)
386 {
387 apr_status_t rv;
388 const apr_pollfd_t *descs = NULL;
389 int num;
390
391 send_msg(s, sa, 0, tc);
392 rv = apr_pollset_poll(pollset, -1, &num, &descs);
393 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
394 ABTS_INT_EQUAL(tc, 1, num);
395 ABTS_PTR_NOTNULL(tc, descs);
396
397 ABTS_PTR_EQUAL(tc, s[0], descs[0].desc.s);
398 ABTS_PTR_EQUAL(tc, s[0], descs[0].client_data);
399 }
400
recv0_pollset(abts_case * tc,void * data)401 static void recv0_pollset(abts_case *tc, void *data)
402 {
403 apr_status_t rv;
404 int lrv;
405 const apr_pollfd_t *descs = NULL;
406
407 recv_msg(s, 0, p, tc);
408 rv = apr_pollset_poll(pollset, 0, &lrv, &descs);
409 ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_TIMEUP(rv));
410 ABTS_INT_EQUAL(tc, 0, lrv);
411 ABTS_PTR_EQUAL(tc, NULL, descs);
412 }
413
send_middle_pollset(abts_case * tc,void * data)414 static void send_middle_pollset(abts_case *tc, void *data)
415 {
416 apr_status_t rv;
417 const apr_pollfd_t *descs = NULL;
418 int num;
419
420 send_msg(s, sa, 2, tc);
421 send_msg(s, sa, 5, tc);
422 rv = apr_pollset_poll(pollset, -1, &num, &descs);
423 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
424 ABTS_PTR_NOTNULL(tc, descs);
425 ABTS_ASSERT(tc, "either one or two events returned",
426 num == 1 || num == 2);
427
428 /* The poll might only see the first sent message, in which
429 * case we just don't bother checking this assertion */
430 if (num == 2) {
431 ABTS_ASSERT(tc, "Incorrect socket in result set",
432 ((descs[0].desc.s == s[2]) && (descs[1].desc.s == s[5])) ||
433 ((descs[0].desc.s == s[5]) && (descs[1].desc.s == s[2])));
434 }
435 }
436
clear_middle_pollset(abts_case * tc,void * data)437 static void clear_middle_pollset(abts_case *tc, void *data)
438 {
439 apr_status_t rv;
440 int lrv;
441 const apr_pollfd_t *descs = NULL;
442
443 recv_msg(s, 2, p, tc);
444 recv_msg(s, 5, p, tc);
445
446 rv = apr_pollset_poll(pollset, 0, &lrv, &descs);
447 ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_TIMEUP(rv));
448 ABTS_INT_EQUAL(tc, 0, lrv);
449 ABTS_PTR_EQUAL(tc, NULL, descs);
450 }
451
send_last_pollset(abts_case * tc,void * data)452 static void send_last_pollset(abts_case *tc, void *data)
453 {
454 apr_status_t rv;
455 const apr_pollfd_t *descs = NULL;
456 int num;
457
458 send_msg(s, sa, LARGE_NUM_SOCKETS - 1, tc);
459 rv = apr_pollset_poll(pollset, -1, &num, &descs);
460 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
461 ABTS_INT_EQUAL(tc, 1, num);
462 ABTS_PTR_NOTNULL(tc, descs);
463
464 ABTS_PTR_EQUAL(tc, s[LARGE_NUM_SOCKETS - 1], descs[0].desc.s);
465 ABTS_PTR_EQUAL(tc, s[LARGE_NUM_SOCKETS - 1], descs[0].client_data);
466 }
467
clear_last_pollset(abts_case * tc,void * data)468 static void clear_last_pollset(abts_case *tc, void *data)
469 {
470 apr_status_t rv;
471 int lrv;
472 const apr_pollfd_t *descs = NULL;
473
474 recv_msg(s, LARGE_NUM_SOCKETS - 1, p, tc);
475
476 rv = apr_pollset_poll(pollset, 0, &lrv, &descs);
477 ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_TIMEUP(rv));
478 ABTS_INT_EQUAL(tc, 0, lrv);
479 ABTS_PTR_EQUAL(tc, NULL, descs);
480 }
481
close_all_sockets(abts_case * tc,void * data)482 static void close_all_sockets(abts_case *tc, void *data)
483 {
484 apr_status_t rv;
485 int i;
486
487 for (i = 0; i < LARGE_NUM_SOCKETS; i++){
488 rv = apr_socket_close(s[i]);
489 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
490 }
491 }
492
pollset_remove(abts_case * tc,void * data)493 static void pollset_remove(abts_case *tc, void *data)
494 {
495 apr_status_t rv;
496 apr_pollset_t *pollset;
497 const apr_pollfd_t *hot_files;
498 apr_pollfd_t pfd;
499 apr_int32_t num;
500
501 rv = apr_pollset_create_ex(&pollset, 5, p, 0,
502 default_pollset_impl);
503 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
504
505 pfd.p = p;
506 pfd.desc_type = APR_POLL_SOCKET;
507 pfd.reqevents = APR_POLLOUT;
508
509 pfd.desc.s = s[0];
510 pfd.client_data = (void *)1;
511 rv = apr_pollset_add(pollset, &pfd);
512 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
513
514 pfd.desc.s = s[1];
515 pfd.client_data = (void *)2;
516 rv = apr_pollset_add(pollset, &pfd);
517 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
518
519 pfd.desc.s = s[2];
520 pfd.client_data = (void *)3;
521 rv = apr_pollset_add(pollset, &pfd);
522 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
523
524 pfd.desc.s = s[3];
525 pfd.client_data = (void *)4;
526 rv = apr_pollset_add(pollset, &pfd);
527 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
528
529 rv = apr_pollset_poll(pollset, 1000, &num, &hot_files);
530 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
531 ABTS_INT_EQUAL(tc, 4, num);
532
533 /* now remove the pollset element referring to desc s[1] */
534 pfd.desc.s = s[1];
535 pfd.client_data = (void *)999; /* not used on this call */
536 rv = apr_pollset_remove(pollset, &pfd);
537 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
538
539 /* this time only three should match */
540 rv = apr_pollset_poll(pollset, 1000, &num, &hot_files);
541 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
542 ABTS_INT_EQUAL(tc, 3, num);
543 ABTS_PTR_EQUAL(tc, (void *)1, hot_files[0].client_data);
544 ABTS_PTR_EQUAL(tc, s[0], hot_files[0].desc.s);
545 ABTS_PTR_EQUAL(tc, (void *)3, hot_files[1].client_data);
546 ABTS_PTR_EQUAL(tc, s[2], hot_files[1].desc.s);
547 ABTS_PTR_EQUAL(tc, (void *)4, hot_files[2].client_data);
548 ABTS_PTR_EQUAL(tc, s[3], hot_files[2].desc.s);
549
550 /* now remove the pollset elements referring to desc s[2] */
551 pfd.desc.s = s[2];
552 pfd.client_data = (void *)999; /* not used on this call */
553 rv = apr_pollset_remove(pollset, &pfd);
554 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
555
556 /* this time only two should match */
557 rv = apr_pollset_poll(pollset, 1000, &num, &hot_files);
558 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
559 ABTS_INT_EQUAL(tc, 2, num);
560 ABTS_ASSERT(tc, "Incorrect socket in result set",
561 ((hot_files[0].desc.s == s[0]) && (hot_files[1].desc.s == s[3])) ||
562 ((hot_files[0].desc.s == s[3]) && (hot_files[1].desc.s == s[0])));
563 ABTS_ASSERT(tc, "Incorrect client data in result set",
564 ((hot_files[0].client_data == (void *)1) &&
565 (hot_files[1].client_data == (void *)4)) ||
566 ((hot_files[0].client_data == (void *)4) &&
567 (hot_files[1].client_data == (void *)1)));
568 }
569
570 #define POLLCB_PREREQ \
571 do { \
572 if (pollcb == NULL) { \
573 ABTS_NOT_IMPL(tc, "pollcb interface not supported"); \
574 return; \
575 } \
576 } while (0)
577
setup_pollcb(abts_case * tc,void * data)578 static void setup_pollcb(abts_case *tc, void *data)
579 {
580 apr_status_t rv;
581 rv = apr_pollcb_create(&pollcb, LARGE_NUM_SOCKETS, p, 0);
582 if (rv == APR_ENOTIMPL) {
583 pollcb = NULL;
584 ABTS_NOT_IMPL(tc, "pollcb interface not supported");
585 }
586 else {
587 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
588 }
589 }
590
591 typedef struct pollcb_baton_t {
592 abts_case *tc;
593 int count;
594 } pollcb_baton_t;
595
trigger_pollcb_cb(void * baton,apr_pollfd_t * descriptor)596 static apr_status_t trigger_pollcb_cb(void* baton, apr_pollfd_t *descriptor)
597 {
598 pollcb_baton_t* pcb = (pollcb_baton_t*) baton;
599 ABTS_PTR_EQUAL(pcb->tc, s[0], descriptor->desc.s);
600 ABTS_PTR_EQUAL(pcb->tc, s[0], descriptor->client_data);
601 pcb->count++;
602 return APR_SUCCESS;
603 }
604
trigger_pollcb(abts_case * tc,void * data)605 static void trigger_pollcb(abts_case *tc, void *data)
606 {
607 apr_status_t rv;
608 apr_pollfd_t socket_pollfd;
609 pollcb_baton_t pcb;
610
611 POLLCB_PREREQ;
612
613 ABTS_PTR_NOTNULL(tc, s[0]);
614 socket_pollfd.desc_type = APR_POLL_SOCKET;
615 socket_pollfd.reqevents = APR_POLLIN;
616 socket_pollfd.desc.s = s[0];
617 socket_pollfd.client_data = s[0];
618 rv = apr_pollcb_add(pollcb, &socket_pollfd);
619 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
620
621 send_msg(s, sa, 0, tc);
622 pcb.tc = tc;
623 pcb.count = 0;
624 rv = apr_pollcb_poll(pollcb, -1, trigger_pollcb_cb, &pcb);
625 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
626 ABTS_INT_EQUAL(tc, 1, pcb.count);
627
628 rv = apr_pollcb_remove(pollcb, &socket_pollfd);
629 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
630 }
631
timeout_pollcb(abts_case * tc,void * data)632 static void timeout_pollcb(abts_case *tc, void *data)
633 {
634 apr_status_t rv;
635 pollcb_baton_t pcb;
636
637 POLLCB_PREREQ;
638
639 pcb.count = 0;
640 pcb.tc = tc;
641
642 rv = apr_pollcb_poll(pollcb, 1, trigger_pollcb_cb, &pcb);
643 ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_TIMEUP(rv));
644 ABTS_INT_EQUAL(tc, 0, pcb.count);
645 }
646
timeout_pollin_pollcb(abts_case * tc,void * data)647 static void timeout_pollin_pollcb(abts_case *tc, void *data)
648 {
649 apr_status_t rv;
650 pollcb_baton_t pcb;
651 apr_pollfd_t socket_pollfd;
652
653 POLLCB_PREREQ;
654
655 recv_msg(s, 0, p, tc);
656
657 ABTS_PTR_NOTNULL(tc, s[0]);
658 socket_pollfd.desc_type = APR_POLL_SOCKET;
659 socket_pollfd.reqevents = APR_POLLIN;
660 socket_pollfd.desc.s = s[0];
661 socket_pollfd.client_data = s[0];
662 rv = apr_pollcb_add(pollcb, &socket_pollfd);
663 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
664
665 pcb.count = 0;
666 pcb.tc = tc;
667
668 rv = apr_pollcb_poll(pollcb, 1, trigger_pollcb_cb, &pcb);
669 ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_TIMEUP(rv));
670 ABTS_INT_EQUAL(tc, 0, pcb.count);
671
672 rv = apr_pollcb_remove(pollcb, &socket_pollfd);
673 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
674 }
675
pollset_default(abts_case * tc,void * data)676 static void pollset_default(abts_case *tc, void *data)
677 {
678 apr_status_t rv1, rv2;
679 apr_pollset_t *pollset;
680
681 /* verify that APR will successfully create a pollset if an invalid method
682 * is specified as long as APR_POLLSET_NODEFAULT isn't specified
683 * (no platform has both APR_POLLSET_PORT and APR_POLLSET_KQUEUE, so at
684 * least one create call will succeed after having to switch to the default
685 * type)
686 */
687 rv1 = apr_pollset_create_ex(&pollset, 1, p, 0, APR_POLLSET_PORT);
688
689 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv1);
690 ABTS_PTR_NOTNULL(tc, pollset);
691
692 rv1 = apr_pollset_create_ex(&pollset, 1, p, 0, APR_POLLSET_KQUEUE);
693 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv1);
694 ABTS_PTR_NOTNULL(tc, pollset);
695
696 /* verify that APR will fail to create a pollset if an invalid method is
697 * specified along with APR_POLLSET_NODEFAULT
698 * (no platform has both APR_POLLSET_PORT and APR_POLLSET_KQUEUE, so at
699 * least one create call will fail since it can't switch to the default
700 * type)
701 */
702 rv1 = apr_pollset_create_ex(&pollset, 1, p, APR_POLLSET_NODEFAULT,
703 APR_POLLSET_PORT);
704
705 if (rv1 == APR_SUCCESS) {
706 ABTS_PTR_NOTNULL(tc, pollset);
707 }
708
709 rv2 = apr_pollset_create_ex(&pollset, 1, p, APR_POLLSET_NODEFAULT,
710 APR_POLLSET_KQUEUE);
711 if (rv2 == APR_SUCCESS) {
712 ABTS_PTR_NOTNULL(tc, pollset);
713 }
714
715 ABTS_ASSERT(tc,
716 "failure using APR_POLLSET_NODEFAULT with unsupported method",
717 rv1 != APR_SUCCESS || rv2 != APR_SUCCESS);
718 }
719
pollcb_default(abts_case * tc,void * data)720 static void pollcb_default(abts_case *tc, void *data)
721 {
722 apr_status_t rv1, rv2;
723 apr_pollcb_t *pollcb;
724
725 /* verify that APR will successfully create a pollcb if an invalid method
726 * is specified as long as APR_POLLSET_NODEFAULT isn't specified
727 * (no platform has both APR_POLLSET_PORT and APR_POLLSET_KQUEUE, so at
728 * least one create call will succeed after having to switch to the default
729 * type)
730 */
731 rv1 = apr_pollcb_create_ex(&pollcb, 1, p, 0, APR_POLLSET_PORT);
732 if (rv1 == APR_ENOTIMPL) {
733 ABTS_NOT_IMPL(tc, "pollcb interface not supported");
734 return;
735 }
736
737 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv1);
738 ABTS_PTR_NOTNULL(tc, pollcb);
739
740 rv1 = apr_pollcb_create_ex(&pollcb, 1, p, 0, APR_POLLSET_KQUEUE);
741 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv1);
742 ABTS_PTR_NOTNULL(tc, pollcb);
743
744 /* verify that APR will fail to create a pollcb if an invalid method is
745 * specified along with APR_POLLSET_NODEFAULT
746 * (no platform has both APR_POLLSET_PORT and APR_POLLSET_KQUEUE, so at
747 * least one create call will fail since it can't switch to the default
748 * type)
749 */
750 rv1 = apr_pollcb_create_ex(&pollcb, 1, p, APR_POLLSET_NODEFAULT,
751 APR_POLLSET_PORT);
752
753 if (rv1 == APR_SUCCESS) {
754 ABTS_PTR_NOTNULL(tc, pollcb);
755 }
756
757 rv2 = apr_pollcb_create_ex(&pollcb, 1, p, APR_POLLSET_NODEFAULT,
758 APR_POLLSET_KQUEUE);
759 if (rv2 == APR_SUCCESS) {
760 ABTS_PTR_NOTNULL(tc, pollcb);
761 }
762
763 ABTS_ASSERT(tc,
764 "failure using APR_POLLSET_NODEFAULT with unsupported method",
765 rv1 != APR_SUCCESS || rv2 != APR_SUCCESS);
766
767
768 /* verify basic behavior for another method fallback case (this caused
769 * APR to crash before r834029)
770 */
771
772 rv1 = apr_pollcb_create_ex(&pollcb, 1, p, 0, APR_POLLSET_POLL);
773 if (rv1 != APR_ENOTIMPL) {
774 ABTS_INT_EQUAL(tc, rv1, APR_SUCCESS);
775 ABTS_PTR_NOTNULL(tc, pollcb);
776 }
777 }
778
pollset_wakeup(abts_case * tc,void * data)779 static void pollset_wakeup(abts_case *tc, void *data)
780 {
781 apr_status_t rv;
782 apr_pollfd_t socket_pollfd;
783 apr_pollset_t *pollset;
784 apr_int32_t num;
785 const apr_pollfd_t *descriptors;
786
787 rv = apr_pollset_create_ex(&pollset, 1, p, APR_POLLSET_WAKEABLE,
788 default_pollset_impl);
789 if (rv == APR_ENOTIMPL) {
790 ABTS_NOT_IMPL(tc, "apr_pollset_wakeup() not supported");
791 return;
792 }
793 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
794
795 /* send wakeup but no data; apr_pollset_poll() should return APR_EINTR */
796 rv = apr_pollset_wakeup(pollset);
797 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
798
799 rv = apr_pollset_poll(pollset, -1, &num, &descriptors);
800 ABTS_INT_EQUAL(tc, APR_EINTR, rv);
801
802 /* send wakeup and data; apr_pollset_poll() should return APR_SUCCESS */
803 socket_pollfd.desc_type = APR_POLL_SOCKET;
804 socket_pollfd.reqevents = APR_POLLIN;
805 socket_pollfd.desc.s = s[0];
806 socket_pollfd.client_data = s[0];
807 rv = apr_pollset_add(pollset, &socket_pollfd);
808 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
809
810 send_msg(s, sa, 0, tc);
811
812 rv = apr_pollset_wakeup(pollset);
813 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
814
815 rv = apr_pollset_poll(pollset, -1, &num, &descriptors);
816 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
817 ABTS_INT_EQUAL(tc, 1, num);
818 }
819
justsleep(abts_case * tc,void * data)820 static void justsleep(abts_case *tc, void *data)
821 {
822 apr_int32_t nsds;
823 const apr_pollfd_t *hot_files;
824 apr_pollset_t *pollset;
825 apr_status_t rv;
826 apr_time_t t1, t2;
827 int i;
828 apr_pollset_method_e methods[] = {
829 APR_POLLSET_DEFAULT,
830 APR_POLLSET_SELECT,
831 APR_POLLSET_KQUEUE,
832 APR_POLLSET_PORT,
833 APR_POLLSET_EPOLL,
834 APR_POLLSET_POLL};
835
836 nsds = 1;
837 t1 = apr_time_now();
838 rv = apr_poll(NULL, 0, &nsds, apr_time_from_msec(200));
839 t2 = apr_time_now();
840 ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_TIMEUP(rv));
841 ABTS_INT_EQUAL(tc, 0, nsds);
842 ABTS_ASSERT(tc,
843 "apr_poll() didn't sleep",
844 (t2 - t1) > apr_time_from_msec(100));
845
846 for (i = 0; i < sizeof methods / sizeof methods[0]; i++) {
847 rv = apr_pollset_create_ex(&pollset, 5, p, 0, methods[i]);
848 if (rv != APR_ENOTIMPL) {
849 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
850
851 nsds = 1;
852 t1 = apr_time_now();
853 rv = apr_pollset_poll(pollset, apr_time_from_msec(200), &nsds,
854 &hot_files);
855 t2 = apr_time_now();
856 ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_TIMEUP(rv));
857 ABTS_INT_EQUAL(tc, 0, nsds);
858 ABTS_ASSERT(tc,
859 "apr_pollset_poll() didn't sleep",
860 (t2 - t1) > apr_time_from_msec(100));
861
862 rv = apr_pollset_destroy(pollset);
863 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
864 }
865
866 rv = apr_pollcb_create_ex(&pollcb, 5, p, 0, methods[0]);
867 if (rv != APR_ENOTIMPL) {
868 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
869
870 t1 = apr_time_now();
871 rv = apr_pollcb_poll(pollcb, apr_time_from_msec(200), NULL, NULL);
872 t2 = apr_time_now();
873 ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_TIMEUP(rv));
874 ABTS_ASSERT(tc,
875 "apr_pollcb_poll() didn't sleep",
876 (t2 - t1) > apr_time_from_msec(100));
877
878 /* no apr_pollcb_destroy() */
879 }
880 }
881 }
882
testpoll(abts_suite * suite)883 abts_suite *testpoll(abts_suite *suite)
884 {
885 suite = ADD_SUITE(suite)
886
887 abts_run_test(suite, create_all_sockets, NULL);
888
889 #ifdef OLD_POLL_INTERFACE
890 abts_run_test(suite, setup_small_poll, NULL);
891 abts_run_test(suite, setup_large_poll, NULL);
892 abts_run_test(suite, nomessage, NULL);
893 abts_run_test(suite, send_2, NULL);
894 abts_run_test(suite, recv_2_send_1, NULL);
895 abts_run_test(suite, send_2_signaled_1, NULL);
896 abts_run_test(suite, recv_1_send_0, NULL);
897 abts_run_test(suite, clear_all_signalled, NULL);
898 abts_run_test(suite, send_large_pollarray, NULL);
899 abts_run_test(suite, recv_large_pollarray, NULL);
900 #endif
901
902 abts_run_test(suite, setup_pollset, NULL);
903 abts_run_test(suite, multi_event_pollset, NULL);
904 abts_run_test(suite, add_sockets_pollset, NULL);
905 abts_run_test(suite, nomessage_pollset, NULL);
906 abts_run_test(suite, send0_pollset, NULL);
907 abts_run_test(suite, recv0_pollset, NULL);
908 abts_run_test(suite, send_middle_pollset, NULL);
909 abts_run_test(suite, clear_middle_pollset, NULL);
910 abts_run_test(suite, send_last_pollset, NULL);
911 abts_run_test(suite, clear_last_pollset, NULL);
912 abts_run_test(suite, pollset_remove, NULL);
913 abts_run_test(suite, close_all_sockets, NULL);
914 abts_run_test(suite, create_all_sockets, NULL);
915 abts_run_test(suite, setup_pollcb, NULL);
916 abts_run_test(suite, trigger_pollcb, NULL);
917 abts_run_test(suite, timeout_pollcb, NULL);
918 abts_run_test(suite, timeout_pollin_pollcb, NULL);
919 abts_run_test(suite, pollset_wakeup, NULL);
920 abts_run_test(suite, close_all_sockets, NULL);
921 abts_run_test(suite, pollset_default, NULL);
922 abts_run_test(suite, pollcb_default, NULL);
923 abts_run_test(suite, justsleep, NULL);
924 return suite;
925 }
926
927