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