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