xref: /aosp_15_r20/external/liburing/test/files-exit-hang-poll.c (revision 25da2bea747f3a93b4c30fd9708b0618ef55a0e6)
1*25da2beaSAndroid Build Coastguard Worker /* SPDX-License-Identifier: MIT */
2*25da2beaSAndroid Build Coastguard Worker /*
3*25da2beaSAndroid Build Coastguard Worker  * Based on a test case from Josef Grieb - test that we can exit without
4*25da2beaSAndroid Build Coastguard Worker  * hanging if we have the task file table pinned by a request that is linked
5*25da2beaSAndroid Build Coastguard Worker  * to another request that doesn't finish.
6*25da2beaSAndroid Build Coastguard Worker  */
7*25da2beaSAndroid Build Coastguard Worker #include <errno.h>
8*25da2beaSAndroid Build Coastguard Worker #include <fcntl.h>
9*25da2beaSAndroid Build Coastguard Worker #include <netinet/in.h>
10*25da2beaSAndroid Build Coastguard Worker #include <stdio.h>
11*25da2beaSAndroid Build Coastguard Worker #include <stdlib.h>
12*25da2beaSAndroid Build Coastguard Worker #include <string.h>
13*25da2beaSAndroid Build Coastguard Worker #include <strings.h>
14*25da2beaSAndroid Build Coastguard Worker #include <sys/socket.h>
15*25da2beaSAndroid Build Coastguard Worker #include <unistd.h>
16*25da2beaSAndroid Build Coastguard Worker #include <poll.h>
17*25da2beaSAndroid Build Coastguard Worker #include "liburing.h"
18*25da2beaSAndroid Build Coastguard Worker 
19*25da2beaSAndroid Build Coastguard Worker #define BACKLOG 512
20*25da2beaSAndroid Build Coastguard Worker 
21*25da2beaSAndroid Build Coastguard Worker #define PORT 9100
22*25da2beaSAndroid Build Coastguard Worker 
23*25da2beaSAndroid Build Coastguard Worker static struct io_uring ring;
24*25da2beaSAndroid Build Coastguard Worker 
add_poll(struct io_uring * ring,int fd)25*25da2beaSAndroid Build Coastguard Worker static void add_poll(struct io_uring *ring, int fd)
26*25da2beaSAndroid Build Coastguard Worker {
27*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
28*25da2beaSAndroid Build Coastguard Worker 
29*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
30*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_poll_add(sqe, fd, POLLIN);
31*25da2beaSAndroid Build Coastguard Worker 	sqe->flags |= IOSQE_IO_LINK;
32*25da2beaSAndroid Build Coastguard Worker }
33*25da2beaSAndroid Build Coastguard Worker 
add_accept(struct io_uring * ring,int fd)34*25da2beaSAndroid Build Coastguard Worker static void add_accept(struct io_uring *ring, int fd)
35*25da2beaSAndroid Build Coastguard Worker {
36*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
37*25da2beaSAndroid Build Coastguard Worker 
38*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
39*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_accept(sqe, fd, 0, 0, SOCK_NONBLOCK | SOCK_CLOEXEC);
40*25da2beaSAndroid Build Coastguard Worker }
41*25da2beaSAndroid Build Coastguard Worker 
setup_io_uring(void)42*25da2beaSAndroid Build Coastguard Worker static int setup_io_uring(void)
43*25da2beaSAndroid Build Coastguard Worker {
44*25da2beaSAndroid Build Coastguard Worker 	int ret;
45*25da2beaSAndroid Build Coastguard Worker 
46*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_queue_init(16, &ring, 0);
47*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
48*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Unable to setup io_uring: %s\n", strerror(-ret));
49*25da2beaSAndroid Build Coastguard Worker 		return 1;
50*25da2beaSAndroid Build Coastguard Worker 	}
51*25da2beaSAndroid Build Coastguard Worker 
52*25da2beaSAndroid Build Coastguard Worker 	return 0;
53*25da2beaSAndroid Build Coastguard Worker }
54*25da2beaSAndroid Build Coastguard Worker 
alarm_sig(int sig)55*25da2beaSAndroid Build Coastguard Worker static void alarm_sig(int sig)
56*25da2beaSAndroid Build Coastguard Worker {
57*25da2beaSAndroid Build Coastguard Worker 	exit(0);
58*25da2beaSAndroid Build Coastguard Worker }
59*25da2beaSAndroid Build Coastguard Worker 
main(int argc,char * argv[])60*25da2beaSAndroid Build Coastguard Worker int main(int argc, char *argv[])
61*25da2beaSAndroid Build Coastguard Worker {
62*25da2beaSAndroid Build Coastguard Worker 	struct sockaddr_in serv_addr;
63*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
64*25da2beaSAndroid Build Coastguard Worker 	int ret, sock_listen_fd;
65*25da2beaSAndroid Build Coastguard Worker 	const int val = 1;
66*25da2beaSAndroid Build Coastguard Worker 	int i;
67*25da2beaSAndroid Build Coastguard Worker 
68*25da2beaSAndroid Build Coastguard Worker 	if (argc > 1)
69*25da2beaSAndroid Build Coastguard Worker 		return 0;
70*25da2beaSAndroid Build Coastguard Worker 
71*25da2beaSAndroid Build Coastguard Worker 	sock_listen_fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
72*25da2beaSAndroid Build Coastguard Worker 	if (sock_listen_fd < 0) {
73*25da2beaSAndroid Build Coastguard Worker 		perror("socket");
74*25da2beaSAndroid Build Coastguard Worker 		return 1;
75*25da2beaSAndroid Build Coastguard Worker 	}
76*25da2beaSAndroid Build Coastguard Worker 
77*25da2beaSAndroid Build Coastguard Worker 	setsockopt(sock_listen_fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
78*25da2beaSAndroid Build Coastguard Worker 
79*25da2beaSAndroid Build Coastguard Worker 	memset(&serv_addr, 0, sizeof(serv_addr));
80*25da2beaSAndroid Build Coastguard Worker 	serv_addr.sin_family = AF_INET;
81*25da2beaSAndroid Build Coastguard Worker 	serv_addr.sin_addr.s_addr = INADDR_ANY;
82*25da2beaSAndroid Build Coastguard Worker 
83*25da2beaSAndroid Build Coastguard Worker 	for (i = 0; i < 100; i++) {
84*25da2beaSAndroid Build Coastguard Worker 		serv_addr.sin_port = htons(PORT + i);
85*25da2beaSAndroid Build Coastguard Worker 
86*25da2beaSAndroid Build Coastguard Worker 		ret = bind(sock_listen_fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
87*25da2beaSAndroid Build Coastguard Worker 		if (!ret)
88*25da2beaSAndroid Build Coastguard Worker 			break;
89*25da2beaSAndroid Build Coastguard Worker 		if (errno != EADDRINUSE) {
90*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "bind: %s\n", strerror(errno));
91*25da2beaSAndroid Build Coastguard Worker 			return 1;
92*25da2beaSAndroid Build Coastguard Worker 		}
93*25da2beaSAndroid Build Coastguard Worker 		if (i == 99) {
94*25da2beaSAndroid Build Coastguard Worker 			printf("Gave up on finding a port, skipping\n");
95*25da2beaSAndroid Build Coastguard Worker 			goto out;
96*25da2beaSAndroid Build Coastguard Worker 		}
97*25da2beaSAndroid Build Coastguard Worker 	}
98*25da2beaSAndroid Build Coastguard Worker 
99*25da2beaSAndroid Build Coastguard Worker 	if (listen(sock_listen_fd, BACKLOG) < 0) {
100*25da2beaSAndroid Build Coastguard Worker 		perror("Error listening on socket\n");
101*25da2beaSAndroid Build Coastguard Worker 		return 1;
102*25da2beaSAndroid Build Coastguard Worker 	}
103*25da2beaSAndroid Build Coastguard Worker 
104*25da2beaSAndroid Build Coastguard Worker 	if (setup_io_uring())
105*25da2beaSAndroid Build Coastguard Worker 		return 1;
106*25da2beaSAndroid Build Coastguard Worker 
107*25da2beaSAndroid Build Coastguard Worker 	add_poll(&ring, sock_listen_fd);
108*25da2beaSAndroid Build Coastguard Worker 	add_accept(&ring, sock_listen_fd);
109*25da2beaSAndroid Build Coastguard Worker 
110*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(&ring);
111*25da2beaSAndroid Build Coastguard Worker 	if (ret != 2) {
112*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "submit=%d\n", ret);
113*25da2beaSAndroid Build Coastguard Worker 		return 1;
114*25da2beaSAndroid Build Coastguard Worker 	}
115*25da2beaSAndroid Build Coastguard Worker 
116*25da2beaSAndroid Build Coastguard Worker 	signal(SIGALRM, alarm_sig);
117*25da2beaSAndroid Build Coastguard Worker 	alarm(1);
118*25da2beaSAndroid Build Coastguard Worker 
119*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_wait_cqe(&ring, &cqe);
120*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
121*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "wait_cqe=%d\n", ret);
122*25da2beaSAndroid Build Coastguard Worker 		return 1;
123*25da2beaSAndroid Build Coastguard Worker 	}
124*25da2beaSAndroid Build Coastguard Worker 
125*25da2beaSAndroid Build Coastguard Worker out:
126*25da2beaSAndroid Build Coastguard Worker 	io_uring_queue_exit(&ring);
127*25da2beaSAndroid Build Coastguard Worker 	return 0;
128*25da2beaSAndroid Build Coastguard Worker }
129