evloop.c 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. #include "../config-host.h"
  2. /* SPDX-License-Identifier: MIT */
  3. /*
  4. * Test that we don't recursively generate completion events if an io_uring
  5. * has an eventfd registered that triggers on completions, and we add a poll
  6. * request with multishot on the eventfd. Older kernels will stop on overflow,
  7. * newer kernels will detect this earlier and abort correctly.
  8. */
  9. #include <errno.h>
  10. #include <stdio.h>
  11. #include <unistd.h>
  12. #include <stdlib.h>
  13. #include <sys/eventfd.h>
  14. #include <sys/types.h>
  15. #include <poll.h>
  16. #include <assert.h>
  17. #include "liburing.h"
  18. #include "helpers.h"
  19. int main(int argc, char *argv[])
  20. {
  21. struct io_uring ring;
  22. struct io_uring_sqe *sqe;
  23. struct io_uring_cqe *cqe;
  24. int ret, efd, i;
  25. if (argc > 1)
  26. return T_EXIT_SKIP;
  27. ret = io_uring_queue_init(8, &ring, 0);
  28. if (ret) {
  29. fprintf(stderr, "Ring init failed: %d\n", ret);
  30. return T_EXIT_FAIL;
  31. }
  32. efd = eventfd(0, 0);
  33. if (efd < 0) {
  34. perror("eventfd");
  35. return T_EXIT_FAIL;
  36. }
  37. ret = io_uring_register_eventfd(&ring, efd);
  38. if (ret) {
  39. fprintf(stderr, "Ring eventfd register failed: %d\n", ret);
  40. return T_EXIT_FAIL;
  41. }
  42. sqe = io_uring_get_sqe(&ring);
  43. io_uring_prep_poll_multishot(sqe, efd, POLLIN);
  44. sqe->user_data = 1;
  45. io_uring_submit(&ring);
  46. sqe = io_uring_get_sqe(&ring);
  47. sqe->user_data = 2;
  48. io_uring_prep_nop(sqe);
  49. io_uring_submit(&ring);
  50. for (i = 0; i < 2; i++) {
  51. ret = io_uring_wait_cqe(&ring, &cqe);
  52. if (ret) {
  53. fprintf(stderr, "wait_cqe ret = %d\n", ret);
  54. break;
  55. }
  56. io_uring_cqe_seen(&ring, cqe);
  57. }
  58. ret = io_uring_peek_cqe(&ring, &cqe);
  59. if (!ret) {
  60. fprintf(stderr, "Generated too many events\n");
  61. return T_EXIT_FAIL;
  62. }
  63. return T_EXIT_PASS;
  64. }