1
/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* 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_pollset_t *pollset;
36
/* ###: tests surrounded by ifdef OLD_POLL_INTERFACE either need to be
37
* converted to use the pollset interface or removed. */
39
#ifdef OLD_POLL_INTERFACE
40
static apr_pollfd_t *pollarray;
41
static apr_pollfd_t *pollarray_large;
44
static void make_socket(apr_socket_t **sock, apr_sockaddr_t **sa,
45
apr_port_t port, apr_pool_t *p, abts_case *tc)
49
rv = apr_sockaddr_info_get(sa, "127.0.0.1", APR_UNSPEC, port, 0, p);
50
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
52
rv = apr_socket_create(sock, (*sa)->family, SOCK_DGRAM, 0, p);
53
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
55
rv =apr_socket_bind((*sock), (*sa));
56
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
59
#ifdef OLD_POLL_INTERFACE
60
static void check_sockets(const apr_pollfd_t *pollarray,
61
apr_socket_t **sockarray, int which, int pollin,
68
rv = apr_poll_revents_get(&event, sockarray[which],
69
(apr_pollfd_t *)pollarray);
70
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
72
str = apr_psprintf(p, "Socket %d not signalled when it should be",
74
ABTS_ASSERT(tc, str, event & APR_POLLIN);
76
str = apr_psprintf(p, "Socket %d signalled when it should not be",
78
ABTS_ASSERT(tc, str, !(event & APR_POLLIN));
83
static void send_msg(apr_socket_t **sockarray, apr_sockaddr_t **sas, int which,
89
ABTS_PTR_NOTNULL(tc, sockarray[which]);
91
rv = apr_socket_sendto(sockarray[which], sas[which], 0, "hello", &len);
92
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
93
ABTS_INT_EQUAL(tc, strlen("hello"), len);
96
static void recv_msg(apr_socket_t **sockarray, int which, apr_pool_t *p,
99
apr_size_t buflen = 5;
100
char *buffer = apr_pcalloc(p, sizeof(char) * (buflen + 1));
101
apr_sockaddr_t *recsa;
104
ABTS_PTR_NOTNULL(tc, sockarray[which]);
106
apr_sockaddr_info_get(&recsa, "127.0.0.1", APR_UNSPEC, 7770, 0, p);
108
rv = apr_socket_recvfrom(recsa, sockarray[which], 0, buffer, &buflen);
109
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
110
ABTS_INT_EQUAL(tc, strlen("hello"), buflen);
111
ABTS_STR_EQUAL(tc, "hello", buffer);
115
static void create_all_sockets(abts_case *tc, void *data)
119
for (i = 0; i < LARGE_NUM_SOCKETS; i++){
120
make_socket(&s[i], &sa[i], 7777 + i, p, tc);
124
#ifdef OLD_POLL_INTERFACE
125
static void setup_small_poll(abts_case *tc, void *data)
130
rv = apr_poll_setup(&pollarray, SMALL_NUM_SOCKETS, p);
131
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
133
for (i = 0; i < SMALL_NUM_SOCKETS;i++){
134
ABTS_INT_EQUAL(tc, 0, pollarray[i].reqevents);
135
ABTS_INT_EQUAL(tc, 0, pollarray[i].rtnevents);
137
rv = apr_poll_socket_add(pollarray, s[i], APR_POLLIN);
138
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
139
ABTS_PTR_EQUAL(tc, s[i], pollarray[i].desc.s);
143
static void setup_large_poll(abts_case *tc, void *data)
148
rv = apr_poll_setup(&pollarray_large, LARGE_NUM_SOCKETS, p);
149
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
151
for (i = 0; i < LARGE_NUM_SOCKETS;i++){
152
ABTS_INT_EQUAL(tc, 0, pollarray_large[i].reqevents);
153
ABTS_INT_EQUAL(tc, 0, pollarray_large[i].rtnevents);
155
rv = apr_poll_socket_add(pollarray_large, s[i], APR_POLLIN);
156
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
157
ABTS_PTR_EQUAL(tc, s[i], pollarray_large[i].desc.s);
161
static void nomessage(abts_case *tc, void *data)
164
int srv = SMALL_NUM_SOCKETS;
166
rv = apr_poll(pollarray, SMALL_NUM_SOCKETS, &srv, 2 * APR_USEC_PER_SEC);
167
ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_TIMEUP(rv));
168
check_sockets(pollarray, s, 0, 0, tc);
169
check_sockets(pollarray, s, 1, 0, tc);
170
check_sockets(pollarray, s, 2, 0, tc);
173
static void send_2(abts_case *tc, void *data)
176
int srv = SMALL_NUM_SOCKETS;
178
send_msg(s, sa, 2, tc);
180
rv = apr_poll(pollarray, SMALL_NUM_SOCKETS, &srv, 2 * APR_USEC_PER_SEC);
181
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
182
check_sockets(pollarray, s, 0, 0, tc);
183
check_sockets(pollarray, s, 1, 0, tc);
184
check_sockets(pollarray, s, 2, 1, tc);
187
static void recv_2_send_1(abts_case *tc, void *data)
190
int srv = SMALL_NUM_SOCKETS;
192
recv_msg(s, 2, p, tc);
193
send_msg(s, sa, 1, tc);
195
rv = apr_poll(pollarray, SMALL_NUM_SOCKETS, &srv, 2 * APR_USEC_PER_SEC);
196
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
197
check_sockets(pollarray, s, 0, 0, tc);
198
check_sockets(pollarray, s, 1, 1, tc);
199
check_sockets(pollarray, s, 2, 0, tc);
202
static void send_2_signaled_1(abts_case *tc, void *data)
205
int srv = SMALL_NUM_SOCKETS;
207
send_msg(s, sa, 2, tc);
209
rv = apr_poll(pollarray, SMALL_NUM_SOCKETS, &srv, 2 * APR_USEC_PER_SEC);
210
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
211
check_sockets(pollarray, s, 0, 0, tc);
212
check_sockets(pollarray, s, 1, 1, tc);
213
check_sockets(pollarray, s, 2, 1, tc);
216
static void recv_1_send_0(abts_case *tc, void *data)
219
int srv = SMALL_NUM_SOCKETS;
221
recv_msg(s, 1, p, tc);
222
send_msg(s, sa, 0, tc);
224
rv = apr_poll(pollarray, SMALL_NUM_SOCKETS, &srv, 2 * APR_USEC_PER_SEC);
225
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
226
check_sockets(pollarray, s, 0, 1, tc);
227
check_sockets(pollarray, s, 1, 0, tc);
228
check_sockets(pollarray, s, 2, 1, tc);
231
static void clear_all_signalled(abts_case *tc, void *data)
234
int srv = SMALL_NUM_SOCKETS;
236
recv_msg(s, 0, p, tc);
237
recv_msg(s, 2, p, tc);
239
rv = apr_poll(pollarray, SMALL_NUM_SOCKETS, &srv, 2 * APR_USEC_PER_SEC);
240
ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_TIMEUP(rv));
241
check_sockets(pollarray, s, 0, 0, tc);
242
check_sockets(pollarray, s, 1, 0, tc);
243
check_sockets(pollarray, s, 2, 0, tc);
246
static void send_large_pollarray(abts_case *tc, void *data)
249
int lrv = LARGE_NUM_SOCKETS;
252
send_msg(s, sa, LARGE_NUM_SOCKETS - 1, tc);
254
rv = apr_poll(pollarray_large, LARGE_NUM_SOCKETS, &lrv,
255
2 * APR_USEC_PER_SEC);
256
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
258
for (i = 0; i < LARGE_NUM_SOCKETS; i++) {
259
if (i == (LARGE_NUM_SOCKETS - 1)) {
260
check_sockets(pollarray_large, s, i, 1, tc);
263
check_sockets(pollarray_large, s, i, 0, tc);
268
static void recv_large_pollarray(abts_case *tc, void *data)
271
int lrv = LARGE_NUM_SOCKETS;
274
recv_msg(s, LARGE_NUM_SOCKETS - 1, p, tc);
276
rv = apr_poll(pollarray_large, LARGE_NUM_SOCKETS, &lrv,
277
2 * APR_USEC_PER_SEC);
278
ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_TIMEUP(rv));
280
for (i = 0; i < LARGE_NUM_SOCKETS; i++) {
281
check_sockets(pollarray_large, s, i, 0, tc);
286
static void setup_pollset(abts_case *tc, void *data)
289
rv = apr_pollset_create(&pollset, LARGE_NUM_SOCKETS, p, 0);
290
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
293
static void multi_event_pollset(abts_case *tc, void *data)
296
apr_pollfd_t socket_pollfd;
298
const apr_pollfd_t *descs = NULL;
300
ABTS_PTR_NOTNULL(tc, s[0]);
301
socket_pollfd.desc_type = APR_POLL_SOCKET;
302
socket_pollfd.reqevents = APR_POLLIN | APR_POLLOUT;
303
socket_pollfd.desc.s = s[0];
304
socket_pollfd.client_data = s[0];
305
rv = apr_pollset_add(pollset, &socket_pollfd);
306
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
308
send_msg(s, sa, 0, tc);
310
rv = apr_pollset_poll(pollset, 0, &lrv, &descs);
311
ABTS_INT_EQUAL(tc, 0, APR_STATUS_IS_TIMEUP(rv));
313
ABTS_PTR_EQUAL(tc, s[0], descs[0].desc.s);
314
ABTS_INT_EQUAL(tc, APR_POLLIN | APR_POLLOUT, descs[0].rtnevents);
315
ABTS_PTR_EQUAL(tc, s[0], descs[0].client_data);
318
ABTS_PTR_EQUAL(tc, s[0], descs[0].desc.s);
319
ABTS_PTR_EQUAL(tc, s[0], descs[0].client_data);
320
ABTS_PTR_EQUAL(tc, s[0], descs[1].desc.s);
321
ABTS_PTR_EQUAL(tc, s[0], descs[1].client_data);
322
ABTS_ASSERT(tc, "returned events incorrect",
323
((descs[0].rtnevents | descs[1].rtnevents)
324
== (APR_POLLIN | APR_POLLOUT))
325
&& descs[0].rtnevents != descs[1].rtnevents);
328
ABTS_ASSERT(tc, "either one or two events returned",
329
lrv == 1 || lrv == 2);
332
recv_msg(s, 0, p, tc);
334
rv = apr_pollset_poll(pollset, 0, &lrv, &descs);
335
ABTS_INT_EQUAL(tc, 0, APR_STATUS_IS_TIMEUP(rv));
336
ABTS_INT_EQUAL(tc, 1, lrv);
337
ABTS_PTR_EQUAL(tc, s[0], descs[0].desc.s);
338
ABTS_INT_EQUAL(tc, APR_POLLOUT, descs[0].rtnevents);
339
ABTS_PTR_EQUAL(tc, s[0], descs[0].client_data);
341
rv = apr_pollset_remove(pollset, &socket_pollfd);
342
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
345
static void add_sockets_pollset(abts_case *tc, void *data)
350
for (i = 0; i < LARGE_NUM_SOCKETS;i++){
351
apr_pollfd_t socket_pollfd;
353
ABTS_PTR_NOTNULL(tc, s[i]);
355
socket_pollfd.desc_type = APR_POLL_SOCKET;
356
socket_pollfd.reqevents = APR_POLLIN;
357
socket_pollfd.desc.s = s[i];
358
socket_pollfd.client_data = s[i];
359
rv = apr_pollset_add(pollset, &socket_pollfd);
360
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
364
static void nomessage_pollset(abts_case *tc, void *data)
368
const apr_pollfd_t *descs = NULL;
370
rv = apr_pollset_poll(pollset, 0, &lrv, &descs);
371
ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_TIMEUP(rv));
372
ABTS_INT_EQUAL(tc, 0, lrv);
373
ABTS_PTR_EQUAL(tc, NULL, descs);
376
static void send0_pollset(abts_case *tc, void *data)
379
const apr_pollfd_t *descs = NULL;
382
send_msg(s, sa, 0, tc);
383
rv = apr_pollset_poll(pollset, 0, &num, &descs);
384
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
385
ABTS_INT_EQUAL(tc, 1, num);
386
ABTS_PTR_NOTNULL(tc, descs);
388
ABTS_PTR_EQUAL(tc, s[0], descs[0].desc.s);
389
ABTS_PTR_EQUAL(tc, s[0], descs[0].client_data);
392
static void recv0_pollset(abts_case *tc, void *data)
396
const apr_pollfd_t *descs = NULL;
398
recv_msg(s, 0, p, tc);
399
rv = apr_pollset_poll(pollset, 0, &lrv, &descs);
400
ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_TIMEUP(rv));
401
ABTS_INT_EQUAL(tc, 0, lrv);
402
ABTS_PTR_EQUAL(tc, NULL, descs);
405
static void send_middle_pollset(abts_case *tc, void *data)
408
const apr_pollfd_t *descs = NULL;
411
send_msg(s, sa, 2, tc);
412
send_msg(s, sa, 5, tc);
413
rv = apr_pollset_poll(pollset, 0, &num, &descs);
414
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
415
ABTS_INT_EQUAL(tc, 2, num);
416
ABTS_PTR_NOTNULL(tc, descs);
418
ABTS_ASSERT(tc, "Incorrect socket in result set",
419
((descs[0].desc.s == s[2]) && (descs[1].desc.s == s[5])) ||
420
((descs[0].desc.s == s[5]) && (descs[1].desc.s == s[2])));
423
static void clear_middle_pollset(abts_case *tc, void *data)
427
const apr_pollfd_t *descs = NULL;
429
recv_msg(s, 2, p, tc);
430
recv_msg(s, 5, p, tc);
432
rv = apr_pollset_poll(pollset, 0, &lrv, &descs);
433
ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_TIMEUP(rv));
434
ABTS_INT_EQUAL(tc, 0, lrv);
435
ABTS_PTR_EQUAL(tc, NULL, descs);
438
static void send_last_pollset(abts_case *tc, void *data)
441
const apr_pollfd_t *descs = NULL;
444
send_msg(s, sa, LARGE_NUM_SOCKETS - 1, tc);
445
rv = apr_pollset_poll(pollset, 0, &num, &descs);
446
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
447
ABTS_INT_EQUAL(tc, 1, num);
448
ABTS_PTR_NOTNULL(tc, descs);
450
ABTS_PTR_EQUAL(tc, s[LARGE_NUM_SOCKETS - 1], descs[0].desc.s);
451
ABTS_PTR_EQUAL(tc, s[LARGE_NUM_SOCKETS - 1], descs[0].client_data);
454
static void clear_last_pollset(abts_case *tc, void *data)
458
const apr_pollfd_t *descs = NULL;
460
recv_msg(s, LARGE_NUM_SOCKETS - 1, p, tc);
462
rv = apr_pollset_poll(pollset, 0, &lrv, &descs);
463
ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_TIMEUP(rv));
464
ABTS_INT_EQUAL(tc, 0, lrv);
465
ABTS_PTR_EQUAL(tc, NULL, descs);
468
static void close_all_sockets(abts_case *tc, void *data)
473
for (i = 0; i < LARGE_NUM_SOCKETS; i++){
474
rv = apr_socket_close(s[i]);
475
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
479
static void pollset_remove(abts_case *tc, void *data)
482
apr_pollset_t *pollset;
483
const apr_pollfd_t *hot_files;
487
rv = apr_pollset_create(&pollset, 5, p, 0);
488
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
491
pfd.desc_type = APR_POLL_SOCKET;
492
pfd.reqevents = APR_POLLOUT;
495
pfd.client_data = (void *)1;
496
rv = apr_pollset_add(pollset, &pfd);
497
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
500
pfd.client_data = (void *)2;
501
rv = apr_pollset_add(pollset, &pfd);
502
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
505
pfd.client_data = (void *)3;
506
rv = apr_pollset_add(pollset, &pfd);
507
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
510
pfd.client_data = (void *)4;
511
rv = apr_pollset_add(pollset, &pfd);
512
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
514
rv = apr_pollset_poll(pollset, 1000, &num, &hot_files);
515
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
516
ABTS_INT_EQUAL(tc, 4, num);
518
/* now remove the pollset element referring to desc s[1] */
520
pfd.client_data = (void *)999; /* not used on this call */
521
rv = apr_pollset_remove(pollset, &pfd);
522
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
524
/* this time only three should match */
525
rv = apr_pollset_poll(pollset, 1000, &num, &hot_files);
526
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
527
ABTS_INT_EQUAL(tc, 3, num);
528
ABTS_PTR_EQUAL(tc, (void *)1, hot_files[0].client_data);
529
ABTS_PTR_EQUAL(tc, s[0], hot_files[0].desc.s);
530
ABTS_PTR_EQUAL(tc, (void *)3, hot_files[1].client_data);
531
ABTS_PTR_EQUAL(tc, s[2], hot_files[1].desc.s);
532
ABTS_PTR_EQUAL(tc, (void *)4, hot_files[2].client_data);
533
ABTS_PTR_EQUAL(tc, s[3], hot_files[2].desc.s);
535
/* now remove the pollset elements referring to desc s[2] */
537
pfd.client_data = (void *)999; /* not used on this call */
538
rv = apr_pollset_remove(pollset, &pfd);
539
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
541
/* this time only two should match */
542
rv = apr_pollset_poll(pollset, 1000, &num, &hot_files);
543
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
544
ABTS_INT_EQUAL(tc, 2, num);
545
ABTS_ASSERT(tc, "Incorrect socket in result set",
546
((hot_files[0].desc.s == s[0]) && (hot_files[1].desc.s == s[3])) ||
547
((hot_files[0].desc.s == s[3]) && (hot_files[1].desc.s == s[0])));
548
ABTS_ASSERT(tc, "Incorrect client data in result set",
549
((hot_files[0].client_data == (void *)1) &&
550
(hot_files[1].client_data == (void *)4)) ||
551
((hot_files[0].client_data == (void *)4) &&
552
(hot_files[1].client_data == (void *)1)));
555
abts_suite *testpoll(abts_suite *suite)
557
suite = ADD_SUITE(suite)
559
abts_run_test(suite, create_all_sockets, NULL);
561
#ifdef OLD_POLL_INTERFACE
562
abts_run_test(suite, setup_small_poll, NULL);
563
abts_run_test(suite, setup_large_poll, NULL);
564
abts_run_test(suite, nomessage, NULL);
565
abts_run_test(suite, send_2, NULL);
566
abts_run_test(suite, recv_2_send_1, NULL);
567
abts_run_test(suite, send_2_signaled_1, NULL);
568
abts_run_test(suite, recv_1_send_0, NULL);
569
abts_run_test(suite, clear_all_signalled, NULL);
570
abts_run_test(suite, send_large_pollarray, NULL);
571
abts_run_test(suite, recv_large_pollarray, NULL);
574
abts_run_test(suite, setup_pollset, NULL);
575
abts_run_test(suite, multi_event_pollset, NULL);
576
abts_run_test(suite, add_sockets_pollset, NULL);
577
abts_run_test(suite, nomessage_pollset, NULL);
578
abts_run_test(suite, send0_pollset, NULL);
579
abts_run_test(suite, recv0_pollset, NULL);
580
abts_run_test(suite, send_middle_pollset, NULL);
581
abts_run_test(suite, clear_middle_pollset, NULL);
582
abts_run_test(suite, send_last_pollset, NULL);
583
abts_run_test(suite, clear_last_pollset, NULL);
585
abts_run_test(suite, pollset_remove, NULL);
587
abts_run_test(suite, close_all_sockets, NULL);