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