xref: /aosp_15_r20/external/cronet/third_party/apache-portable-runtime/src/test/testpoll.c (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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