1 /* $NetBSD: t_eventfd.c,v 1.3 2022/02/20 15:21:14 thorpej Exp $ */ 2 3 /*- 4 * Copyright (c) 2020 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 __COPYRIGHT("@(#) Copyright (c) 2020\ 31 The NetBSD Foundation, inc. All rights reserved."); 32 __RCSID("$NetBSD: t_eventfd.c,v 1.3 2022/02/20 15:21:14 thorpej Exp $"); 33 34 #include <sys/types.h> 35 #include <sys/event.h> 36 #include <sys/eventfd.h> 37 #include <sys/ioctl.h> 38 #include <sys/select.h> 39 #include <sys/stat.h> 40 #include <sys/syscall.h> 41 #include <errno.h> 42 #include <poll.h> 43 #include <pthread.h> 44 #include <stdlib.h> 45 #include <stdio.h> 46 #include <time.h> 47 #include <unistd.h> 48 49 #include <atf-c.h> 50 51 struct helper_context { 52 int efd; 53 54 pthread_mutex_t mutex; 55 pthread_cond_t cond; 56 pthread_barrier_t barrier; 57 int state; 58 }; 59 60 static void 61 init_helper_context(struct helper_context * const ctx) 62 { 63 pthread_condattr_t condattr; 64 65 memset(ctx, 0, sizeof(*ctx)); 66 67 ATF_REQUIRE(pthread_mutex_init(&ctx->mutex, NULL) == 0); 68 69 ATF_REQUIRE(pthread_condattr_init(&condattr) == 0); 70 ATF_REQUIRE(pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC) == 0); 71 ATF_REQUIRE(pthread_cond_init(&ctx->cond, &condattr) == 0); 72 ATF_REQUIRE(pthread_condattr_destroy(&condattr) == 0); 73 74 ATF_REQUIRE(pthread_barrier_init(&ctx->barrier, NULL, 2) == 0); 75 } 76 77 static void 78 set_state(struct helper_context * const ctx, int const new) 79 { 80 pthread_mutex_lock(&ctx->mutex); 81 ctx->state = new; 82 pthread_cond_signal(&ctx->cond); 83 pthread_mutex_unlock(&ctx->mutex); 84 } 85 86 static int 87 get_state(struct helper_context * const ctx) 88 { 89 int rv; 90 91 pthread_mutex_lock(&ctx->mutex); 92 rv = ctx->state; 93 pthread_mutex_unlock(&ctx->mutex); 94 95 return rv; 96 } 97 98 static bool 99 wait_state(struct helper_context * const ctx, int const val) 100 { 101 struct timespec deadline; 102 int error; 103 bool rv; 104 105 pthread_mutex_lock(&ctx->mutex); 106 107 ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &deadline) == 0); 108 deadline.tv_sec += 5; 109 110 while (ctx->state != val) { 111 error = pthread_cond_timedwait(&ctx->cond, &ctx->mutex, 112 &deadline); 113 if (error) { 114 break; 115 } 116 } 117 rv = ctx->state == val; 118 119 pthread_mutex_unlock(&ctx->mutex); 120 121 return rv; 122 } 123 124 static bool 125 wait_barrier(struct helper_context * const ctx) 126 { 127 int rv = pthread_barrier_wait(&ctx->barrier); 128 129 return rv == 0 || rv == PTHREAD_BARRIER_SERIAL_THREAD; 130 } 131 132 /*****************************************************************************/ 133 134 static void * 135 eventfd_normal_helper(void * const v) 136 { 137 struct helper_context * const ctx = v; 138 eventfd_t efd_value; 139 140 ATF_REQUIRE(wait_barrier(ctx)); 141 142 /* Read the value. This will reset it to zero. */ 143 ATF_REQUIRE(get_state(ctx) == 666); 144 ATF_REQUIRE(eventfd_read(ctx->efd, &efd_value) == 0); 145 146 /* Assert the value. */ 147 ATF_REQUIRE(efd_value == 0xcafebabe); 148 149 set_state(ctx, 0); 150 151 /* Wait for the main thread to prep the next test. */ 152 ATF_REQUIRE(wait_barrier(ctx)); 153 154 /* Read the value. */ 155 ATF_REQUIRE(eventfd_read(ctx->efd, &efd_value) == 0); 156 157 /* Assert the value. */ 158 ATF_REQUIRE(efd_value == 0xbeefcafe); 159 160 ATF_REQUIRE(wait_barrier(ctx)); 161 162 return NULL; 163 } 164 165 ATF_TC(eventfd_normal); 166 ATF_TC_HEAD(eventfd_normal, tc) 167 { 168 atf_tc_set_md_var(tc, "descr", 169 "validates basic normal eventfd operation"); 170 } 171 ATF_TC_BODY(eventfd_normal, tc) 172 { 173 struct helper_context ctx; 174 pthread_t helper; 175 void *join_val; 176 177 init_helper_context(&ctx); 178 179 ATF_REQUIRE((ctx.efd = eventfd(0, 0)) >= 0); 180 181 ATF_REQUIRE(pthread_create(&helper, NULL, 182 eventfd_normal_helper, &ctx) == 0); 183 184 /* 185 * Wait for the helper to block in read(). Give it some time 186 * so that if the read fails or returns immediately, we'll 187 * notice. 188 */ 189 set_state(&ctx, 666); 190 ATF_REQUIRE(wait_barrier(&ctx)); 191 sleep(2); 192 ATF_REQUIRE(get_state(&ctx) == 666); 193 194 /* Write a distinct value; helper will assert it. */ 195 ATF_REQUIRE(eventfd_write(ctx.efd, 0xcafebabe) == 0); 196 197 /* Wait for helper to read the value. */ 198 ATF_REQUIRE(wait_state(&ctx, 0)); 199 200 /* Helper is now blocked in a barrier. */ 201 202 /* Test additive property of the efd value. */ 203 ATF_REQUIRE(eventfd_write(ctx.efd, 0x0000cafe) == 0); 204 ATF_REQUIRE(eventfd_write(ctx.efd, 0xbeef0000) == 0); 205 206 /* Satisfy the barrier; helper will read value and assert 0xbeefcafe. */ 207 ATF_REQUIRE(wait_barrier(&ctx)); 208 209 /* And wait for it to finish. */ 210 ATF_REQUIRE(wait_barrier(&ctx)); 211 212 /* Reap the helper. */ 213 ATF_REQUIRE(pthread_join(helper, &join_val) == 0); 214 215 (void) close(ctx.efd); 216 } 217 218 /*****************************************************************************/ 219 220 ATF_TC(eventfd_semaphore); 221 ATF_TC_HEAD(eventfd_semaphore, tc) 222 { 223 atf_tc_set_md_var(tc, "descr", 224 "validates semaphore and non-blocking eventfd operation"); 225 } 226 ATF_TC_BODY(eventfd_semaphore, tc) 227 { 228 eventfd_t efd_value; 229 int efd; 230 231 ATF_REQUIRE((efd = eventfd(3, EFD_SEMAPHORE | EFD_NONBLOCK)) >= 0); 232 233 /* 3 reads should succeed without blocking. */ 234 ATF_REQUIRE(eventfd_read(efd, &efd_value) == 0); 235 ATF_REQUIRE(efd_value == 1); 236 237 ATF_REQUIRE(eventfd_read(efd, &efd_value) == 0); 238 ATF_REQUIRE(efd_value == 1); 239 240 ATF_REQUIRE(eventfd_read(efd, &efd_value) == 0); 241 ATF_REQUIRE(efd_value == 1); 242 243 /* This one should block. */ 244 ATF_REQUIRE_ERRNO(EAGAIN, 245 eventfd_read(efd, &efd_value) == -1); 246 247 /* Add 1 to the semaphore. */ 248 ATF_REQUIRE(eventfd_write(efd, 1) == 0); 249 250 /* One more read allowed. */ 251 ATF_REQUIRE(eventfd_read(efd, &efd_value) == 0); 252 ATF_REQUIRE(efd_value == 1); 253 254 /* And this one again should block. */ 255 ATF_REQUIRE_ERRNO(EAGAIN, 256 eventfd_read(efd, &efd_value) == -1); 257 258 (void) close(efd); 259 } 260 261 /*****************************************************************************/ 262 263 ATF_TC(eventfd_select_poll_kevent_immed); 264 ATF_TC_HEAD(eventfd_select_poll_kevent_immed, tc) 265 { 266 atf_tc_set_md_var(tc, "descr", 267 "validates select/poll/kevent behavior - immediate return"); 268 } 269 ATF_TC_BODY(eventfd_select_poll_kevent_immed, tc) 270 { 271 const struct timespec ts = { .tv_sec = 0, .tv_nsec = 0 }; 272 struct timeval tv; 273 struct pollfd fds[1]; 274 fd_set readfds, writefds, exceptfds; 275 int efd; 276 int kq; 277 struct kevent kev[2]; 278 279 ATF_REQUIRE((efd = eventfd(0, EFD_NONBLOCK)) >= 0); 280 281 ATF_REQUIRE((kq = kqueue()) >= 0); 282 EV_SET(&kev[0], efd, EVFILT_READ, EV_ADD, 0, 0, NULL); 283 EV_SET(&kev[1], efd, EVFILT_WRITE, EV_ADD, 0, 0, NULL); 284 ATF_REQUIRE(kevent(kq, kev, 2, NULL, 0, &ts) == 0); 285 286 /* 287 * efd should be writable but not readable. Pass all of the 288 * event bits; we should only get back POLLOUT | POLLWRNORM. 289 */ 290 fds[0].fd = efd; 291 fds[0].events = POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI | 292 POLLOUT | POLLWRNORM | POLLWRBAND | POLLHUP; 293 fds[0].revents = 0; 294 ATF_REQUIRE(poll(fds, 1, 0) == 1); 295 ATF_REQUIRE(fds[0].revents == (POLLOUT | POLLWRNORM)); 296 297 /* 298 * As above; efd should only be set in writefds upon return 299 * from the select() call. 300 */ 301 FD_ZERO(&readfds); 302 FD_ZERO(&writefds); 303 FD_ZERO(&exceptfds); 304 tv.tv_sec = 0; 305 tv.tv_usec = 0; 306 FD_SET(efd, &readfds); 307 FD_SET(efd, &writefds); 308 FD_SET(efd, &exceptfds); 309 ATF_REQUIRE(select(efd + 1, &readfds, &writefds, &exceptfds, &tv) == 1); 310 ATF_REQUIRE(!FD_ISSET(efd, &readfds)); 311 ATF_REQUIRE(FD_ISSET(efd, &writefds)); 312 ATF_REQUIRE(!FD_ISSET(efd, &exceptfds)); 313 314 /* 315 * Check that we get an EVFILT_WRITE event (and only that event) 316 * on efd. 317 */ 318 memset(kev, 0, sizeof(kev)); 319 ATF_REQUIRE(kevent(kq, NULL, 0, kev, 2, &ts) == 1); 320 ATF_REQUIRE(kev[0].ident == (uintptr_t)efd); 321 ATF_REQUIRE(kev[0].filter == EVFILT_WRITE); 322 ATF_REQUIRE((kev[0].flags & (EV_EOF | EV_ERROR)) == 0); 323 ATF_REQUIRE(kev[0].data == 0); 324 325 /* 326 * Write the maximum value into the eventfd. This should result 327 * in the eventfd becoming readable but NOT writable. 328 */ 329 ATF_REQUIRE(eventfd_write(efd, UINT64_MAX - 1) == 0); 330 331 fds[0].fd = efd; 332 fds[0].events = POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI | 333 POLLOUT | POLLWRNORM | POLLWRBAND | POLLHUP; 334 fds[0].revents = 0; 335 ATF_REQUIRE(poll(fds, 1, 0) == 1); 336 ATF_REQUIRE(fds[0].revents == (POLLIN | POLLRDNORM)); 337 338 FD_ZERO(&readfds); 339 FD_ZERO(&writefds); 340 FD_ZERO(&exceptfds); 341 tv.tv_sec = 0; 342 tv.tv_usec = 0; 343 FD_SET(efd, &readfds); 344 FD_SET(efd, &writefds); 345 FD_SET(efd, &exceptfds); 346 ATF_REQUIRE(select(efd + 1, &readfds, &writefds, &exceptfds, &tv) == 1); 347 ATF_REQUIRE(FD_ISSET(efd, &readfds)); 348 ATF_REQUIRE(!FD_ISSET(efd, &writefds)); 349 ATF_REQUIRE(!FD_ISSET(efd, &exceptfds)); 350 351 /* 352 * Check that we get an EVFILT_READ event (and only that event) 353 * on efd. 354 */ 355 memset(kev, 0, sizeof(kev)); 356 ATF_REQUIRE(kevent(kq, NULL, 0, kev, 2, &ts) == 1); 357 ATF_REQUIRE(kev[0].ident == (uintptr_t)efd); 358 ATF_REQUIRE(kev[0].filter == EVFILT_READ); 359 ATF_REQUIRE((kev[0].flags & (EV_EOF | EV_ERROR)) == 0); 360 ATF_REQUIRE(kev[0].data == (int64_t)(UINT64_MAX - 1)); 361 362 (void) close(kq); 363 (void) close(efd); 364 } 365 366 /*****************************************************************************/ 367 368 static void * 369 eventfd_select_poll_kevent_block_helper(void * const v) 370 { 371 struct helper_context * const ctx = v; 372 struct pollfd fds[1]; 373 fd_set selfds; 374 eventfd_t efd_value; 375 int kq; 376 struct kevent kev[1]; 377 378 fds[0].fd = ctx->efd; 379 fds[0].events = POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI; 380 fds[0].revents = 0; 381 382 ATF_REQUIRE_ERRNO(EAGAIN, 383 eventfd_read(ctx->efd, &efd_value) == -1); 384 385 ATF_REQUIRE(wait_barrier(ctx)); 386 387 ATF_REQUIRE(get_state(ctx) == 666); 388 ATF_REQUIRE(poll(fds, 1, INFTIM) == 1); 389 ATF_REQUIRE(fds[0].revents == (POLLIN | POLLRDNORM)); 390 set_state(ctx, 0); 391 392 ATF_REQUIRE(wait_barrier(ctx)); 393 394 /* 395 * The maximum value was written to the eventfd, so we 396 * should block waiting for writability. 397 */ 398 fds[0].fd = ctx->efd; 399 fds[0].events = POLLOUT | POLLWRNORM; 400 fds[0].revents = 0; 401 402 ATF_REQUIRE_ERRNO(EAGAIN, 403 eventfd_write(ctx->efd, UINT64_MAX - 1) == -1); 404 405 ATF_REQUIRE(wait_barrier(ctx)); 406 407 ATF_REQUIRE(get_state(ctx) == 666); 408 ATF_REQUIRE(poll(fds, 1, INFTIM) == 1); 409 ATF_REQUIRE(fds[0].revents == (POLLOUT | POLLWRNORM)); 410 set_state(ctx, 0); 411 412 ATF_REQUIRE(wait_barrier(ctx)); 413 414 /* 415 * Now, the same dance again, with select(). 416 */ 417 418 FD_ZERO(&selfds); 419 FD_SET(ctx->efd, &selfds); 420 421 ATF_REQUIRE_ERRNO(EAGAIN, 422 eventfd_read(ctx->efd, &efd_value) == -1); 423 424 ATF_REQUIRE(wait_barrier(ctx)); 425 426 ATF_REQUIRE(get_state(ctx) == 666); 427 ATF_REQUIRE(select(ctx->efd + 1, &selfds, NULL, NULL, NULL) == 1); 428 ATF_REQUIRE(FD_ISSET(ctx->efd, &selfds)); 429 set_state(ctx, 0); 430 431 ATF_REQUIRE(wait_barrier(ctx)); 432 433 FD_ZERO(&selfds); 434 FD_SET(ctx->efd, &selfds); 435 436 ATF_REQUIRE_ERRNO(EAGAIN, 437 eventfd_write(ctx->efd, UINT64_MAX - 1) == -1); 438 439 ATF_REQUIRE(wait_barrier(ctx)); 440 441 ATF_REQUIRE(get_state(ctx) == 666); 442 ATF_REQUIRE(select(ctx->efd + 1, NULL, &selfds, NULL, NULL) == 1); 443 ATF_REQUIRE(FD_ISSET(ctx->efd, &selfds)); 444 set_state(ctx, 0); 445 446 ATF_REQUIRE(wait_barrier(ctx)); 447 448 /* 449 * Now, the same dance again, with kevent(). 450 */ 451 ATF_REQUIRE((kq = kqueue()) >= 0); 452 453 EV_SET(&kev[0], ctx->efd, EVFILT_READ, EV_ADD | EV_ONESHOT, 0, 0, NULL); 454 ATF_REQUIRE(kevent(kq, kev, 1, NULL, 0, NULL) == 0); 455 456 ATF_REQUIRE_ERRNO(EAGAIN, 457 eventfd_read(ctx->efd, &efd_value) == -1); 458 459 ATF_REQUIRE(wait_barrier(ctx)); 460 461 ATF_REQUIRE(get_state(ctx) == 666); 462 ATF_REQUIRE(kevent(kq, NULL, 0, kev, 1, NULL) == 1); 463 ATF_REQUIRE(kev[0].ident == (uintptr_t)ctx->efd); 464 ATF_REQUIRE(kev[0].filter == EVFILT_READ); 465 ATF_REQUIRE((kev[0].flags & (EV_EOF | EV_ERROR)) == 0); 466 ATF_REQUIRE(kev[0].data == (int64_t)(UINT64_MAX - 1)); 467 set_state(ctx, 0); 468 469 ATF_REQUIRE(wait_barrier(ctx)); 470 471 EV_SET(&kev[0], ctx->efd, EVFILT_WRITE, EV_ADD | EV_ONESHOT, 0, 0, 472 NULL); 473 ATF_REQUIRE(kevent(kq, kev, 1, NULL, 0, NULL) == 0); 474 475 ATF_REQUIRE_ERRNO(EAGAIN, 476 eventfd_write(ctx->efd, UINT64_MAX - 1) == -1); 477 478 ATF_REQUIRE(wait_barrier(ctx)); 479 480 ATF_REQUIRE(get_state(ctx) == 666); 481 ATF_REQUIRE(kevent(kq, NULL, 0, kev, 1, NULL) == 1); 482 ATF_REQUIRE(kev[0].ident == (uintptr_t)ctx->efd); 483 ATF_REQUIRE(kev[0].filter == EVFILT_WRITE); 484 ATF_REQUIRE((kev[0].flags & (EV_EOF | EV_ERROR)) == 0); 485 ATF_REQUIRE(kev[0].data == 0); 486 set_state(ctx, 0); 487 488 ATF_REQUIRE(wait_barrier(ctx)); 489 490 (void) close(kq); 491 492 return NULL; 493 } 494 495 ATF_TC(eventfd_select_poll_kevent_block); 496 ATF_TC_HEAD(eventfd_select_poll_kevent_block, tc) 497 { 498 atf_tc_set_md_var(tc, "descr", 499 "validates select/poll/kevent behavior - return after blocking"); 500 } 501 ATF_TC_BODY(eventfd_select_poll_kevent_block, tc) 502 { 503 struct helper_context ctx; 504 pthread_t helper; 505 eventfd_t efd_value; 506 void *join_val; 507 508 init_helper_context(&ctx); 509 510 ATF_REQUIRE((ctx.efd = eventfd(0, EFD_NONBLOCK)) >= 0); 511 512 ATF_REQUIRE(pthread_create(&helper, NULL, 513 eventfd_select_poll_kevent_block_helper, 514 &ctx) == 0); 515 516 /* 517 * Wait for the helper to block in poll(). Give it some time 518 * so that if the poll returns immediately, we'll notice. 519 */ 520 set_state(&ctx, 666); 521 ATF_REQUIRE(wait_barrier(&ctx)); 522 sleep(2); 523 ATF_REQUIRE(get_state(&ctx) == 666); 524 525 /* 526 * Write the max value to the eventfd so that it becomes readable 527 * and unblocks the helper waiting in poll(). 528 */ 529 ATF_REQUIRE(eventfd_write(ctx.efd, UINT64_MAX - 1) == 0); 530 531 /* 532 * Ensure the helper woke from the poll() call. 533 */ 534 ATF_REQUIRE(wait_barrier(&ctx)); 535 ATF_REQUIRE(get_state(&ctx) == 0); 536 537 /* 538 * Wait for the helper to block in poll(), this time waiting 539 * for writability. 540 */ 541 set_state(&ctx, 666); 542 ATF_REQUIRE(wait_barrier(&ctx)); 543 sleep(2); 544 ATF_REQUIRE(get_state(&ctx) == 666); 545 546 /* 547 * Now read the value, which will reset the eventfd to 0 and 548 * unblock the poll() call. 549 */ 550 ATF_REQUIRE(eventfd_read(ctx.efd, &efd_value) == 0); 551 ATF_REQUIRE(efd_value == UINT64_MAX - 1); 552 553 /* 554 * Ensure that the helper woke from the poll() call. 555 */ 556 ATF_REQUIRE(wait_barrier(&ctx)); 557 ATF_REQUIRE(get_state(&ctx) == 0); 558 559 /* 560 * Wait for the helper to block in select(), waiting for readability. 561 */ 562 set_state(&ctx, 666); 563 ATF_REQUIRE(wait_barrier(&ctx)); 564 sleep(2); 565 ATF_REQUIRE(get_state(&ctx) == 666); 566 567 /* 568 * Write the max value to the eventfd so that it becomes readable 569 * and unblocks the helper waiting in select(). 570 */ 571 efd_value = UINT64_MAX - 1; 572 ATF_REQUIRE(eventfd_write(ctx.efd, UINT64_MAX - 1) == 0); 573 574 /* 575 * Ensure the helper woke from the select() call. 576 */ 577 ATF_REQUIRE(wait_barrier(&ctx)); 578 ATF_REQUIRE(get_state(&ctx) == 0); 579 580 /* 581 * Wait for the helper to block in select(), this time waiting 582 * for writability. 583 */ 584 set_state(&ctx, 666); 585 ATF_REQUIRE(wait_barrier(&ctx)); 586 sleep(2); 587 ATF_REQUIRE(get_state(&ctx) == 666); 588 589 /* 590 * Now read the value, which will reset the eventfd to 0 and 591 * unblock the select() call. 592 */ 593 ATF_REQUIRE(eventfd_read(ctx.efd, &efd_value) == 0); 594 ATF_REQUIRE(efd_value == UINT64_MAX - 1); 595 596 /* 597 * Ensure that the helper woke from the select() call. 598 */ 599 ATF_REQUIRE(wait_barrier(&ctx)); 600 ATF_REQUIRE(get_state(&ctx) == 0); 601 602 /* 603 * Wait for the helper to block in kevent(), waiting for readability. 604 */ 605 set_state(&ctx, 666); 606 ATF_REQUIRE(wait_barrier(&ctx)); 607 sleep(2); 608 ATF_REQUIRE(get_state(&ctx) == 666); 609 610 /* 611 * Write the max value to the eventfd so that it becomes readable 612 * and unblocks the helper waiting in kevent(). 613 */ 614 efd_value = UINT64_MAX - 1; 615 ATF_REQUIRE(eventfd_write(ctx.efd, UINT64_MAX - 1) == 0); 616 617 /* 618 * Ensure the helper woke from the kevent() call. 619 */ 620 ATF_REQUIRE(wait_barrier(&ctx)); 621 ATF_REQUIRE(get_state(&ctx) == 0); 622 623 /* 624 * Wait for the helper to block in kevent(), this time waiting 625 * for writability. 626 */ 627 set_state(&ctx, 666); 628 ATF_REQUIRE(wait_barrier(&ctx)); 629 sleep(2); 630 ATF_REQUIRE(get_state(&ctx) == 666); 631 632 /* 633 * Now read the value, which will reset the eventfd to 0 and 634 * unblock the select() call. 635 */ 636 ATF_REQUIRE(eventfd_read(ctx.efd, &efd_value) == 0); 637 ATF_REQUIRE(efd_value == UINT64_MAX - 1); 638 639 /* 640 * Ensure that the helper woke from the kevent() call. 641 */ 642 ATF_REQUIRE(wait_barrier(&ctx)); 643 ATF_REQUIRE(get_state(&ctx) == 0); 644 645 /* Reap the helper. */ 646 ATF_REQUIRE(pthread_join(helper, &join_val) == 0); 647 648 (void) close(ctx.efd); 649 } 650 651 /*****************************************************************************/ 652 653 static void * 654 eventfd_restart_helper(void * const v) 655 { 656 struct helper_context * const ctx = v; 657 eventfd_t efd_value; 658 659 /* 660 * Issue a single read to ensure that the descriptor is valid. 661 * Thius will not block because it was created with an initial 662 * count of 1. 663 */ 664 ATF_REQUIRE(eventfd_read(ctx->efd, &efd_value) == 0); 665 ATF_REQUIRE(efd_value == 1); 666 667 ATF_REQUIRE(wait_barrier(ctx)); 668 669 /* 670 * Block in read. The main thread will close the descriptor, 671 * which should unblock us and result in EBADF. 672 */ 673 ATF_REQUIRE(get_state(ctx) == 666); 674 ATF_REQUIRE_ERRNO(EBADF, eventfd_read(ctx->efd, &efd_value) == -1); 675 set_state(ctx, 0); 676 677 ATF_REQUIRE(wait_barrier(ctx)); 678 679 return NULL; 680 } 681 682 ATF_TC(eventfd_restart); 683 ATF_TC_HEAD(eventfd_restart, tc) 684 { 685 atf_tc_set_md_var(tc, "descr", 686 "exercises the 'restart' fileop code path"); 687 } 688 ATF_TC_BODY(eventfd_restart, tc) 689 { 690 struct helper_context ctx; 691 pthread_t helper; 692 void *join_val; 693 694 init_helper_context(&ctx); 695 696 ATF_REQUIRE((ctx.efd = eventfd(1, 0)) >= 0); 697 698 ATF_REQUIRE(pthread_create(&helper, NULL, 699 eventfd_restart_helper, &ctx) == 0); 700 701 /* 702 * Wait for the helper to block in read(). Give it some time 703 * so that if the poll returns immediately, we'll notice. 704 */ 705 set_state(&ctx, 666); 706 ATF_REQUIRE(wait_barrier(&ctx)); 707 sleep(2); 708 ATF_REQUIRE(get_state(&ctx) == 666); 709 710 /* 711 * Close the descriptor. This should unblock the reader, 712 * and cause it to receive EBADF. 713 */ 714 ATF_REQUIRE(close(ctx.efd) == 0); 715 716 /* 717 * Ensure that the helper woke from the read() call. 718 */ 719 ATF_REQUIRE(wait_barrier(&ctx)); 720 ATF_REQUIRE(get_state(&ctx) == 0); 721 722 /* Reap the helper. */ 723 ATF_REQUIRE(pthread_join(helper, &join_val) == 0); 724 } 725 726 /*****************************************************************************/ 727 728 ATF_TC(eventfd_badflags); 729 ATF_TC_HEAD(eventfd_badflags, tc) 730 { 731 atf_tc_set_md_var(tc, "descr", 732 "validates behavior when eventfd() called with bad flags"); 733 } 734 ATF_TC_BODY(eventfd_badflags, tc) 735 { 736 ATF_REQUIRE_ERRNO(EINVAL, 737 eventfd(0, ~(EFD_SEMAPHORE | EFD_CLOEXEC | EFD_NONBLOCK)) == -1); 738 } 739 740 /*****************************************************************************/ 741 742 ATF_TC(eventfd_bufsize); 743 ATF_TC_HEAD(eventfd_bufsize, tc) 744 { 745 atf_tc_set_md_var(tc, "descr", 746 "validates expected buffer size behavior"); 747 } 748 ATF_TC_BODY(eventfd_bufsize, tc) 749 { 750 eventfd_t efd_value[2]; 751 int efd; 752 753 ATF_REQUIRE((efd = eventfd(1, EFD_NONBLOCK)) >= 0); 754 755 ATF_REQUIRE_ERRNO(EINVAL, 756 read(efd, efd_value, sizeof(efd_value[0]) - 1) == -1); 757 758 efd_value[0] = 0xdeadbeef; 759 efd_value[1] = 0xdeadbeef; 760 ATF_REQUIRE(read(efd, efd_value, sizeof(efd_value)) == 761 sizeof(efd_value[0])); 762 ATF_REQUIRE(efd_value[0] == 1); 763 ATF_REQUIRE(efd_value[1] == 0xdeadbeef); 764 765 ATF_REQUIRE_ERRNO(EINVAL, 766 write(efd, efd_value, sizeof(efd_value[0]) - 1) == -1); 767 ATF_REQUIRE(write(efd, efd_value, sizeof(efd_value)) == 768 sizeof(efd_value[0])); 769 770 ATF_REQUIRE(read(efd, efd_value, sizeof(efd_value)) == 771 sizeof(efd_value[0])); 772 ATF_REQUIRE(efd_value[0] == 1); 773 ATF_REQUIRE(efd_value[1] == 0xdeadbeef); 774 775 (void) close(efd); 776 } 777 778 /*****************************************************************************/ 779 780 ATF_TC(eventfd_fcntl); 781 ATF_TC_HEAD(eventfd_fcntl, tc) 782 { 783 atf_tc_set_md_var(tc, "descr", 784 "validates fcntl behavior"); 785 } 786 ATF_TC_BODY(eventfd_fcntl, tc) 787 { 788 int efd; 789 int val; 790 791 ATF_REQUIRE((efd = eventfd(1, 0)) >= 0); 792 ATF_REQUIRE((fcntl(efd, F_GETFL) & O_NONBLOCK) == 0); 793 ATF_REQUIRE(fcntl(efd, F_SETFL, O_NONBLOCK) == 0); 794 ATF_REQUIRE((fcntl(efd, F_GETFL) & O_NONBLOCK) != 0); 795 ATF_REQUIRE((fcntl(efd, F_GETFD) & FD_CLOEXEC) == 0); 796 797 ATF_REQUIRE(ioctl(efd, FIONREAD, &val) == 0); 798 ATF_REQUIRE(val == sizeof(eventfd_t)); 799 800 ATF_REQUIRE(ioctl(efd, FIONWRITE, &val) == 0); 801 ATF_REQUIRE(val == 0); 802 803 ATF_REQUIRE_ERRNO(ENOTTY, ioctl(efd, FIONSPACE, &val) == -1); 804 (void)close(efd); 805 806 ATF_REQUIRE((efd = eventfd(1, EFD_NONBLOCK | EFD_CLOEXEC)) >= 0); 807 ATF_REQUIRE((fcntl(efd, F_GETFL) & ~O_ACCMODE) == O_NONBLOCK); 808 ATF_REQUIRE((fcntl(efd, F_GETFD) & FD_CLOEXEC) != 0); 809 ATF_REQUIRE(fcntl(efd, F_SETFD, 0) == 0); 810 ATF_REQUIRE((fcntl(efd, F_GETFD) & FD_CLOEXEC) == 0); 811 ATF_REQUIRE(fcntl(efd, F_SETFD, FD_CLOEXEC) == 0); 812 ATF_REQUIRE((fcntl(efd, F_GETFD) & FD_CLOEXEC) != 0); 813 (void)close(efd); 814 } 815 816 /*****************************************************************************/ 817 818 ATF_TP_ADD_TCS(tp) 819 { 820 ATF_TP_ADD_TC(tp, eventfd_normal); 821 ATF_TP_ADD_TC(tp, eventfd_semaphore); 822 ATF_TP_ADD_TC(tp, eventfd_badflags); 823 ATF_TP_ADD_TC(tp, eventfd_bufsize); 824 ATF_TP_ADD_TC(tp, eventfd_select_poll_kevent_immed); 825 ATF_TP_ADD_TC(tp, eventfd_select_poll_kevent_block); 826 ATF_TP_ADD_TC(tp, eventfd_restart); 827 ATF_TP_ADD_TC(tp, eventfd_fcntl); 828 829 return atf_no_error(); 830 } 831