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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include "apr_strings.h"
19 #include "apr_errno.h"
20 #include "apr_general.h"
22 #include "apr_network_io.h"
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.
30 #define LARGE_NUM_SOCKETS 50
32 static apr_socket_t *s[LARGE_NUM_SOCKETS];
33 static apr_sockaddr_t *sa[LARGE_NUM_SOCKETS];
34 static apr_pollfd_t *pollarray;
35 static apr_pollfd_t *pollarray_large;
36 static apr_pollset_t *pollset;
38 static void make_socket(apr_socket_t **sock, apr_sockaddr_t **sa,
39 apr_port_t port, apr_pool_t *p, CuTest *tc)
43 rv = apr_sockaddr_info_get(sa, "127.0.0.1", APR_UNSPEC, port, 0, p);
44 CuAssertIntEquals(tc, APR_SUCCESS, rv);
46 rv = apr_socket_create(sock, (*sa)->family, SOCK_DGRAM, p);
47 CuAssertIntEquals(tc, APR_SUCCESS, rv);
49 rv =apr_socket_bind((*sock), (*sa));
50 CuAssertIntEquals(tc, APR_SUCCESS, rv);
53 static void check_sockets(const apr_pollfd_t *pollarray,
54 apr_socket_t **sockarray, int which, int pollin,
61 rv = apr_poll_revents_get(&event, sockarray[which],
62 (apr_pollfd_t *)pollarray);
63 CuAssertIntEquals(tc, APR_SUCCESS, rv);
65 str = apr_psprintf(p, "Socket %d not signalled when it should be",
67 CuAssert(tc, str, event & APR_POLLIN);
69 str = apr_psprintf(p, "Socket %d signalled when it should not be",
71 CuAssert(tc, str, !(event & APR_POLLIN));
75 static void send_msg(apr_socket_t **sockarray, apr_sockaddr_t **sas, int which,
81 CuAssertPtrNotNull(tc, sockarray[which]);
83 rv = apr_socket_sendto(sockarray[which], sas[which], 0, "hello", &len);
84 CuAssertIntEquals(tc, APR_SUCCESS, rv);
85 CuAssertIntEquals(tc, strlen("hello"), len);
88 static void recv_msg(apr_socket_t **sockarray, int which, apr_pool_t *p,
91 apr_size_t buflen = 5;
92 char *buffer = apr_pcalloc(p, sizeof(char) * (buflen + 1));
93 apr_sockaddr_t *recsa;
96 CuAssertPtrNotNull(tc, sockarray[which]);
98 apr_sockaddr_info_get(&recsa, "127.0.0.1", APR_UNSPEC, 7770, 0, p);
100 rv = apr_socket_recvfrom(recsa, sockarray[which], 0, buffer, &buflen);
101 CuAssertIntEquals(tc, APR_SUCCESS, rv);
102 CuAssertIntEquals(tc, strlen("hello"), buflen);
103 CuAssertStrEquals(tc, "hello", buffer);
107 static void create_all_sockets(CuTest *tc)
111 for (i = 0; i < LARGE_NUM_SOCKETS; i++){
112 make_socket(&s[i], &sa[i], 7777 + i, p, tc);
116 static void setup_small_poll(CuTest *tc)
121 rv = apr_poll_setup(&pollarray, SMALL_NUM_SOCKETS, p);
122 CuAssertIntEquals(tc, APR_SUCCESS, rv);
124 for (i = 0; i < SMALL_NUM_SOCKETS;i++){
125 CuAssertIntEquals(tc, 0, pollarray[i].reqevents);
126 CuAssertIntEquals(tc, 0, pollarray[i].rtnevents);
128 rv = apr_poll_socket_add(pollarray, s[i], APR_POLLIN);
129 CuAssertIntEquals(tc, APR_SUCCESS, rv);
130 CuAssertPtrEquals(tc, s[i], pollarray[i].desc.s);
134 static void setup_large_poll(CuTest *tc)
139 rv = apr_poll_setup(&pollarray_large, LARGE_NUM_SOCKETS, p);
140 CuAssertIntEquals(tc, APR_SUCCESS, rv);
142 for (i = 0; i < LARGE_NUM_SOCKETS;i++){
143 CuAssertIntEquals(tc, 0, pollarray_large[i].reqevents);
144 CuAssertIntEquals(tc, 0, pollarray_large[i].rtnevents);
146 rv = apr_poll_socket_add(pollarray_large, s[i], APR_POLLIN);
147 CuAssertIntEquals(tc, APR_SUCCESS, rv);
148 CuAssertPtrEquals(tc, s[i], pollarray_large[i].desc.s);
152 static void nomessage(CuTest *tc)
155 int srv = SMALL_NUM_SOCKETS;
157 rv = apr_poll(pollarray, SMALL_NUM_SOCKETS, &srv, 2 * APR_USEC_PER_SEC);
158 CuAssertIntEquals(tc, 1, APR_STATUS_IS_TIMEUP(rv));
159 check_sockets(pollarray, s, 0, 0, tc);
160 check_sockets(pollarray, s, 1, 0, tc);
161 check_sockets(pollarray, s, 2, 0, tc);
164 static void send_2(CuTest *tc)
167 int srv = SMALL_NUM_SOCKETS;
169 send_msg(s, sa, 2, tc);
171 rv = apr_poll(pollarray, SMALL_NUM_SOCKETS, &srv, 2 * APR_USEC_PER_SEC);
172 CuAssertIntEquals(tc, APR_SUCCESS, rv);
173 check_sockets(pollarray, s, 0, 0, tc);
174 check_sockets(pollarray, s, 1, 0, tc);
175 check_sockets(pollarray, s, 2, 1, tc);
178 static void recv_2_send_1(CuTest *tc)
181 int srv = SMALL_NUM_SOCKETS;
183 recv_msg(s, 2, p, tc);
184 send_msg(s, sa, 1, tc);
186 rv = apr_poll(pollarray, SMALL_NUM_SOCKETS, &srv, 2 * APR_USEC_PER_SEC);
187 CuAssertIntEquals(tc, APR_SUCCESS, rv);
188 check_sockets(pollarray, s, 0, 0, tc);
189 check_sockets(pollarray, s, 1, 1, tc);
190 check_sockets(pollarray, s, 2, 0, tc);
193 static void send_2_signaled_1(CuTest *tc)
196 int srv = SMALL_NUM_SOCKETS;
198 send_msg(s, sa, 2, tc);
200 rv = apr_poll(pollarray, SMALL_NUM_SOCKETS, &srv, 2 * APR_USEC_PER_SEC);
201 CuAssertIntEquals(tc, APR_SUCCESS, rv);
202 check_sockets(pollarray, s, 0, 0, tc);
203 check_sockets(pollarray, s, 1, 1, tc);
204 check_sockets(pollarray, s, 2, 1, tc);
207 static void recv_1_send_0(CuTest *tc)
210 int srv = SMALL_NUM_SOCKETS;
212 recv_msg(s, 1, p, tc);
213 send_msg(s, sa, 0, tc);
215 rv = apr_poll(pollarray, SMALL_NUM_SOCKETS, &srv, 2 * APR_USEC_PER_SEC);
216 CuAssertIntEquals(tc, APR_SUCCESS, rv);
217 check_sockets(pollarray, s, 0, 1, tc);
218 check_sockets(pollarray, s, 1, 0, tc);
219 check_sockets(pollarray, s, 2, 1, tc);
222 static void clear_all_signalled(CuTest *tc)
225 int srv = SMALL_NUM_SOCKETS;
227 recv_msg(s, 0, p, tc);
228 recv_msg(s, 2, p, tc);
230 rv = apr_poll(pollarray, SMALL_NUM_SOCKETS, &srv, 2 * APR_USEC_PER_SEC);
231 CuAssertIntEquals(tc, 1, APR_STATUS_IS_TIMEUP(rv));
232 check_sockets(pollarray, s, 0, 0, tc);
233 check_sockets(pollarray, s, 1, 0, tc);
234 check_sockets(pollarray, s, 2, 0, tc);
237 static void send_large_pollarray(CuTest *tc)
240 int lrv = LARGE_NUM_SOCKETS;
243 send_msg(s, sa, LARGE_NUM_SOCKETS - 1, tc);
245 rv = apr_poll(pollarray_large, LARGE_NUM_SOCKETS, &lrv,
246 2 * APR_USEC_PER_SEC);
247 CuAssertIntEquals(tc, APR_SUCCESS, rv);
249 for (i = 0; i < LARGE_NUM_SOCKETS; i++) {
250 if (i == (LARGE_NUM_SOCKETS - 1)) {
251 check_sockets(pollarray_large, s, i, 1, tc);
254 check_sockets(pollarray_large, s, i, 0, tc);
259 static void recv_large_pollarray(CuTest *tc)
262 int lrv = LARGE_NUM_SOCKETS;
265 recv_msg(s, LARGE_NUM_SOCKETS - 1, p, tc);
267 rv = apr_poll(pollarray_large, LARGE_NUM_SOCKETS, &lrv,
268 2 * APR_USEC_PER_SEC);
269 CuAssertIntEquals(tc, 1, APR_STATUS_IS_TIMEUP(rv));
271 for (i = 0; i < LARGE_NUM_SOCKETS; i++) {
272 check_sockets(pollarray_large, s, i, 0, tc);
276 static void setup_pollset(CuTest *tc)
279 rv = apr_pollset_create(&pollset, LARGE_NUM_SOCKETS, p, 0);
280 CuAssertIntEquals(tc, APR_SUCCESS, rv);
283 static void add_sockets_pollset(CuTest *tc)
288 for (i = 0; i < LARGE_NUM_SOCKETS;i++){
289 apr_pollfd_t socket_pollfd;
291 CuAssertPtrNotNull(tc, s[i]);
293 socket_pollfd.desc_type = APR_POLL_SOCKET;
294 socket_pollfd.reqevents = APR_POLLIN;
295 socket_pollfd.desc.s = s[i];
296 socket_pollfd.client_data = s[i];
297 rv = apr_pollset_add(pollset, &socket_pollfd);
298 CuAssertIntEquals(tc, APR_SUCCESS, rv);
302 static void nomessage_pollset(CuTest *tc)
306 const apr_pollfd_t *descs = NULL;
308 rv = apr_pollset_poll(pollset, 0, &lrv, &descs);
309 CuAssertIntEquals(tc, 1, APR_STATUS_IS_TIMEUP(rv));
310 CuAssertIntEquals(tc, 0, lrv);
311 CuAssertPtrEquals(tc, NULL, descs);
314 static void send0_pollset(CuTest *tc)
317 const apr_pollfd_t *descs = NULL;
320 send_msg(s, sa, 0, tc);
321 rv = apr_pollset_poll(pollset, 0, &num, &descs);
322 CuAssertIntEquals(tc, APR_SUCCESS, rv);
323 CuAssertIntEquals(tc, 1, num);
324 CuAssertPtrNotNull(tc, descs);
326 CuAssertPtrEquals(tc, s[0], descs[0].desc.s);
327 CuAssertPtrEquals(tc, s[0], descs[0].client_data);
330 static void recv0_pollset(CuTest *tc)
334 const apr_pollfd_t *descs = NULL;
336 recv_msg(s, 0, p, tc);
337 rv = apr_pollset_poll(pollset, 0, &lrv, &descs);
338 CuAssertIntEquals(tc, 1, APR_STATUS_IS_TIMEUP(rv));
339 CuAssertIntEquals(tc, 0, lrv);
340 CuAssertPtrEquals(tc, NULL, descs);
343 static void send_middle_pollset(CuTest *tc)
346 const apr_pollfd_t *descs = NULL;
349 send_msg(s, sa, 2, tc);
350 send_msg(s, sa, 5, tc);
351 rv = apr_pollset_poll(pollset, 0, &num, &descs);
352 CuAssertIntEquals(tc, APR_SUCCESS, rv);
353 CuAssertIntEquals(tc, 2, num);
354 CuAssertPtrNotNull(tc, descs);
356 CuAssert(tc, "Incorrect socket in result set",
357 ((descs[0].desc.s == s[2]) && (descs[1].desc.s == s[5])) ||
358 ((descs[0].desc.s == s[5]) && (descs[1].desc.s == s[2])));
361 static void clear_middle_pollset(CuTest *tc)
365 const apr_pollfd_t *descs = NULL;
367 recv_msg(s, 2, p, tc);
368 recv_msg(s, 5, p, tc);
370 rv = apr_pollset_poll(pollset, 0, &lrv, &descs);
371 CuAssertIntEquals(tc, 1, APR_STATUS_IS_TIMEUP(rv));
372 CuAssertIntEquals(tc, 0, lrv);
373 CuAssertPtrEquals(tc, NULL, descs);
376 static void send_last_pollset(CuTest *tc)
379 const apr_pollfd_t *descs = NULL;
382 send_msg(s, sa, LARGE_NUM_SOCKETS - 1, tc);
383 rv = apr_pollset_poll(pollset, 0, &num, &descs);
384 CuAssertIntEquals(tc, APR_SUCCESS, rv);
385 CuAssertIntEquals(tc, 1, num);
386 CuAssertPtrNotNull(tc, descs);
388 CuAssertPtrEquals(tc, s[LARGE_NUM_SOCKETS - 1], descs[0].desc.s);
389 CuAssertPtrEquals(tc, s[LARGE_NUM_SOCKETS - 1], descs[0].client_data);
392 static void clear_last_pollset(CuTest *tc)
396 const apr_pollfd_t *descs = NULL;
398 recv_msg(s, LARGE_NUM_SOCKETS - 1, p, tc);
400 rv = apr_pollset_poll(pollset, 0, &lrv, &descs);
401 CuAssertIntEquals(tc, 1, APR_STATUS_IS_TIMEUP(rv));
402 CuAssertIntEquals(tc, 0, lrv);
403 CuAssertPtrEquals(tc, NULL, descs);
406 static void close_all_sockets(CuTest *tc)
411 for (i = 0; i < LARGE_NUM_SOCKETS; i++){
412 rv = apr_socket_close(s[i]);
413 CuAssertIntEquals(tc, APR_SUCCESS, rv);
417 static void pollset_remove(CuTest *tc)
420 apr_pollset_t *pollset;
421 const apr_pollfd_t *hot_files;
425 rv = apr_pollset_create(&pollset, 5, p, 0);
426 CuAssertIntEquals(tc, APR_SUCCESS, rv);
429 pfd.desc_type = APR_POLL_SOCKET;
430 pfd.reqevents = APR_POLLOUT;
433 pfd.client_data = (void *)1;
434 rv = apr_pollset_add(pollset, &pfd);
435 CuAssertIntEquals(tc, APR_SUCCESS, rv);
438 pfd.client_data = (void *)2;
439 rv = apr_pollset_add(pollset, &pfd);
440 CuAssertIntEquals(tc, APR_SUCCESS, rv);
443 pfd.client_data = (void *)3;
444 rv = apr_pollset_add(pollset, &pfd);
445 CuAssertIntEquals(tc, APR_SUCCESS, rv);
448 pfd.client_data = (void *)4;
449 rv = apr_pollset_add(pollset, &pfd);
450 CuAssertIntEquals(tc, APR_SUCCESS, rv);
453 pfd.client_data = (void *)5;
454 rv = apr_pollset_add(pollset, &pfd);
455 CuAssertIntEquals(tc, APR_SUCCESS, rv);
457 rv = apr_pollset_poll(pollset, 1000, &num, &hot_files);
458 CuAssertIntEquals(tc, APR_SUCCESS, rv);
459 CuAssertIntEquals(tc, 5, num);
461 /* now remove the pollset elements referring to desc s[1] */
463 pfd.client_data = (void *)999; /* not used on this call */
464 rv = apr_pollset_remove(pollset, &pfd);
465 CuAssertIntEquals(tc, APR_SUCCESS, rv);
467 /* this time only three should match */
468 rv = apr_pollset_poll(pollset, 1000, &num, &hot_files);
469 CuAssertIntEquals(tc, APR_SUCCESS, rv);
470 CuAssertIntEquals(tc, 3, num);
471 CuAssertPtrEquals(tc, (void *)1, hot_files[0].client_data);
472 CuAssertPtrEquals(tc, s[0], hot_files[0].desc.s);
473 CuAssertPtrEquals(tc, (void *)3, hot_files[1].client_data);
474 CuAssertPtrEquals(tc, s[2], hot_files[1].desc.s);
475 CuAssertPtrEquals(tc, (void *)5, hot_files[2].client_data);
476 CuAssertPtrEquals(tc, s[3], hot_files[2].desc.s);
478 /* now remove the pollset elements referring to desc s[2] */
480 pfd.client_data = (void *)999; /* not used on this call */
481 rv = apr_pollset_remove(pollset, &pfd);
482 CuAssertIntEquals(tc, APR_SUCCESS, rv);
484 /* this time only two should match */
485 rv = apr_pollset_poll(pollset, 1000, &num, &hot_files);
486 CuAssertIntEquals(tc, APR_SUCCESS, rv);
487 CuAssertIntEquals(tc, 2, num);
488 CuAssertPtrEquals(tc, (void *)1, hot_files[0].client_data);
489 CuAssertPtrEquals(tc, s[0], hot_files[0].desc.s);
490 CuAssertPtrEquals(tc, (void *)5, hot_files[1].client_data);
491 CuAssertPtrEquals(tc, s[3], hot_files[1].desc.s);
494 CuSuite *testpoll(void)
496 CuSuite *suite = CuSuiteNew("Poll");
498 SUITE_ADD_TEST(suite, create_all_sockets);
499 SUITE_ADD_TEST(suite, setup_small_poll);
500 SUITE_ADD_TEST(suite, setup_large_poll);
501 SUITE_ADD_TEST(suite, nomessage);
502 SUITE_ADD_TEST(suite, send_2);
503 SUITE_ADD_TEST(suite, recv_2_send_1);
504 SUITE_ADD_TEST(suite, send_2_signaled_1);
505 SUITE_ADD_TEST(suite, recv_1_send_0);
506 SUITE_ADD_TEST(suite, clear_all_signalled);
507 SUITE_ADD_TEST(suite, send_large_pollarray);
508 SUITE_ADD_TEST(suite, recv_large_pollarray);
510 SUITE_ADD_TEST(suite, setup_pollset);
511 SUITE_ADD_TEST(suite, add_sockets_pollset);
512 SUITE_ADD_TEST(suite, nomessage_pollset);
513 SUITE_ADD_TEST(suite, send0_pollset);
514 SUITE_ADD_TEST(suite, recv0_pollset);
515 SUITE_ADD_TEST(suite, send_middle_pollset);
516 SUITE_ADD_TEST(suite, clear_middle_pollset);
517 SUITE_ADD_TEST(suite, send_last_pollset);
518 SUITE_ADD_TEST(suite, clear_last_pollset);
520 SUITE_ADD_TEST(suite, pollset_remove);
522 SUITE_ADD_TEST(suite, close_all_sockets);