| 389 | } |
| 390 | |
| 391 | static void test_dispatch(int fd_read, int fd_write) |
| 392 | { |
| 393 | #ifdef EV_DISPATCH |
| 394 | int kqfd; |
| 395 | struct kevent changes[1]; |
| 396 | struct kevent events[2]; |
| 397 | int n; |
| 398 | char buf[8]; |
| 399 | |
| 400 | kqfd = kqueue(); |
| 401 | if (kqfd < 0) { |
| 402 | fail("kqueue() failed (dispatch)"); |
| 403 | return; |
| 404 | } |
| 405 | |
| 406 | EV_SET(&changes[0], fd_read, EVFILT_READ, |
| 407 | EV_ADD | EV_ENABLE | EV_DISPATCH, 0, 0, (void *) 0x33); |
| 408 | if (kevent(kqfd, changes, 1, NULL, 0, NULL) < 0) { |
| 409 | fail("kevent add dispatch failed"); |
| 410 | return; |
| 411 | } |
| 412 | |
| 413 | if (write(fd_write, "y", 1) != 1) { |
| 414 | fail("write failed (dispatch)"); |
| 415 | return; |
| 416 | } |
| 417 | |
| 418 | memset(events, 0, sizeof(events)); |
| 419 | n = kevent(kqfd, NULL, 0, events, 2, &(struct timespec){1, 0}); |
| 420 | if (n != 1 || events[0].filter != EVFILT_READ) { |
| 421 | fail("dispatch: first read event missing"); |
| 422 | return; |
| 423 | } |
| 424 | |
| 425 | (void) read(fd_read, buf, sizeof(buf)); |
| 426 | |
| 427 | /* The event should be disabled after the first delivery. */ |
| 428 | memset(events, 0, sizeof(events)); |
| 429 | n = kevent(kqfd, NULL, 0, events, 2, &(struct timespec){0, 0}); |
| 430 | if (n != 0) { |
| 431 | fail("dispatch: event should be disabled"); |
| 432 | return; |
| 433 | } |
| 434 | |
| 435 | /* Re-enable and verify it fires again. */ |
| 436 | EV_SET(&changes[0], fd_read, EVFILT_READ, EV_ENABLE, 0, 0, NULL); |
| 437 | if (kevent(kqfd, changes, 1, NULL, 0, NULL) < 0) { |
| 438 | fail("dispatch: enable failed"); |
| 439 | return; |
| 440 | } |
| 441 | |
| 442 | if (write(fd_write, "z", 1) != 1) { |
| 443 | fail("write failed (dispatch re-enable)"); |
| 444 | return; |
| 445 | } |
| 446 | |
| 447 | memset(events, 0, sizeof(events)); |
| 448 | n = kevent(kqfd, NULL, 0, events, 2, &(struct timespec){1, 0}); |