• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: MIT */
2 /*
3  * Description: test io_uring poll cancel handling
4  *
5  */
6 #include <errno.h>
7 #include <stdio.h>
8 #include <unistd.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <inttypes.h>
12 #include <sys/poll.h>
13 #include <sys/wait.h>
14 #include <sys/signal.h>
15 
16 #include "liburing.h"
17 
18 struct poll_data {
19 	unsigned is_poll;
20 	unsigned is_cancel;
21 };
22 
sig_alrm(int sig)23 static void sig_alrm(int sig)
24 {
25 	fprintf(stderr, "Timed out!\n");
26 	exit(1);
27 }
28 
main(int argc,char * argv[])29 int main(int argc, char *argv[])
30 {
31 	struct io_uring ring;
32 	int pipe1[2];
33 	struct io_uring_cqe *cqe;
34 	struct io_uring_sqe *sqe;
35 	struct poll_data *pd, pds[2];
36 	struct sigaction act;
37 	int ret;
38 
39 	if (argc > 1)
40 		return 0;
41 
42 	if (pipe(pipe1) != 0) {
43 		perror("pipe");
44 		return 1;
45 	}
46 
47 	ret = io_uring_queue_init(2, &ring, 0);
48 	if (ret) {
49 		fprintf(stderr, "ring setup failed: %d\n", ret);
50 		return 1;
51 	}
52 
53 	memset(&act, 0, sizeof(act));
54 	act.sa_handler = sig_alrm;
55 	act.sa_flags = SA_RESTART;
56 	sigaction(SIGALRM, &act, NULL);
57 	alarm(1);
58 
59 	sqe = io_uring_get_sqe(&ring);
60 	if (!sqe) {
61 		fprintf(stderr, "get sqe failed\n");
62 		return 1;
63 	}
64 
65 	io_uring_prep_poll_add(sqe, pipe1[0], POLLIN);
66 
67 	pds[0].is_poll = 1;
68 	pds[0].is_cancel = 0;
69 	io_uring_sqe_set_data(sqe, &pds[0]);
70 
71 	ret = io_uring_submit(&ring);
72 	if (ret <= 0) {
73 		fprintf(stderr, "sqe submit failed\n");
74 		return 1;
75 	}
76 
77 	sqe = io_uring_get_sqe(&ring);
78 	if (!sqe) {
79 		fprintf(stderr, "get sqe failed\n");
80 		return 1;
81 	}
82 
83 	pds[1].is_poll = 0;
84 	pds[1].is_cancel = 1;
85 	io_uring_prep_poll_remove(sqe, &pds[0]);
86 	io_uring_sqe_set_data(sqe, &pds[1]);
87 
88 	ret = io_uring_submit(&ring);
89 	if (ret <= 0) {
90 		fprintf(stderr, "sqe submit failed: %d\n", ret);
91 		return 1;
92 	}
93 
94 	ret = io_uring_wait_cqe(&ring, &cqe);
95 	if (ret < 0) {
96 		fprintf(stderr, "wait cqe failed: %d\n", ret);
97 		return 1;
98 	}
99 
100 	pd = io_uring_cqe_get_data(cqe);
101 	if (pd->is_poll && cqe->res != -ECANCELED) {
102 		fprintf(stderr ,"sqe (add=%d/remove=%d) failed with %ld\n",
103 					pd->is_poll, pd->is_cancel,
104 					(long) cqe->res);
105 		return 1;
106 	} else if (pd->is_cancel && cqe->res) {
107 		fprintf(stderr, "sqe (add=%d/remove=%d) failed with %ld\n",
108 					pd->is_poll, pd->is_cancel,
109 					(long) cqe->res);
110 		return 1;
111 	}
112 	io_uring_cqe_seen(&ring, cqe);
113 
114 	ret = io_uring_wait_cqe(&ring, &cqe);
115 	if (ret < 0) {
116 		fprintf(stderr, "wait_cqe: %d\n", ret);
117 		return 1;
118 	}
119 
120 	pd = io_uring_cqe_get_data(cqe);
121 	if (pd->is_poll && cqe->res != -ECANCELED) {
122 		fprintf(stderr, "sqe (add=%d/remove=%d) failed with %ld\n",
123 					pd->is_poll, pd->is_cancel,
124 					(long) cqe->res);
125 		return 1;
126 	} else if (pd->is_cancel && cqe->res) {
127 		fprintf(stderr, "sqe (add=%d/remove=%d) failed with %ld\n",
128 					pd->is_poll, pd->is_cancel,
129 					(long) cqe->res);
130 		return 1;
131 	}
132 
133 	io_uring_cqe_seen(&ring, cqe);
134 	return 0;
135 }
136