sqpoll-exit-hang.c 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #include "../config-host.h"
  2. /* SPDX-License-Identifier: MIT */
  3. /*
  4. * Test that we exit properly with SQPOLL and having a request that
  5. * adds a circular reference to the ring itself.
  6. */
  7. #include <errno.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <unistd.h>
  11. #include <sys/time.h>
  12. #include <poll.h>
  13. #include "liburing.h"
  14. static unsigned long long mtime_since(const struct timeval *s,
  15. const struct timeval *e)
  16. {
  17. long long sec, usec;
  18. sec = e->tv_sec - s->tv_sec;
  19. usec = (e->tv_usec - s->tv_usec);
  20. if (sec > 0 && usec < 0) {
  21. sec--;
  22. usec += 1000000;
  23. }
  24. sec *= 1000;
  25. usec /= 1000;
  26. return sec + usec;
  27. }
  28. static unsigned long long mtime_since_now(struct timeval *tv)
  29. {
  30. struct timeval end;
  31. gettimeofday(&end, NULL);
  32. return mtime_since(tv, &end);
  33. }
  34. int main(int argc, char *argv[])
  35. {
  36. struct io_uring_params p = {};
  37. struct timeval tv;
  38. struct io_uring ring;
  39. struct io_uring_sqe *sqe;
  40. int ret;
  41. if (argc > 1)
  42. return 0;
  43. p.flags = IORING_SETUP_SQPOLL;
  44. p.sq_thread_idle = 100;
  45. ret = io_uring_queue_init_params(1, &ring, &p);
  46. if (ret) {
  47. if (geteuid()) {
  48. printf("%s: skipped, not root\n", argv[0]);
  49. return 0;
  50. }
  51. fprintf(stderr, "queue_init=%d\n", ret);
  52. return 1;
  53. }
  54. if (!(p.features & IORING_FEAT_SQPOLL_NONFIXED)) {
  55. fprintf(stdout, "Skipping\n");
  56. return 0;
  57. }
  58. sqe = io_uring_get_sqe(&ring);
  59. io_uring_prep_poll_add(sqe, ring.ring_fd, POLLIN);
  60. io_uring_submit(&ring);
  61. gettimeofday(&tv, NULL);
  62. do {
  63. usleep(1000);
  64. } while (mtime_since_now(&tv) < 1000);
  65. return 0;
  66. }