xref: /aosp_15_r20/external/liburing/test/poll-cancel-all.c (revision 25da2bea747f3a93b4c30fd9708b0618ef55a0e6)
1*25da2beaSAndroid Build Coastguard Worker /* SPDX-License-Identifier: MIT */
2*25da2beaSAndroid Build Coastguard Worker /*
3*25da2beaSAndroid Build Coastguard Worker  * Description: Test IORING_ASYNC_CANCEL_{ALL,FD}
4*25da2beaSAndroid Build Coastguard Worker  *
5*25da2beaSAndroid Build Coastguard Worker  */
6*25da2beaSAndroid Build Coastguard Worker #include <errno.h>
7*25da2beaSAndroid Build Coastguard Worker #include <stdio.h>
8*25da2beaSAndroid Build Coastguard Worker #include <unistd.h>
9*25da2beaSAndroid Build Coastguard Worker #include <stdlib.h>
10*25da2beaSAndroid Build Coastguard Worker #include <string.h>
11*25da2beaSAndroid Build Coastguard Worker #include <poll.h>
12*25da2beaSAndroid Build Coastguard Worker 
13*25da2beaSAndroid Build Coastguard Worker #include "liburing.h"
14*25da2beaSAndroid Build Coastguard Worker 
15*25da2beaSAndroid Build Coastguard Worker static int no_cancel_flags;
16*25da2beaSAndroid Build Coastguard Worker 
test1(struct io_uring * ring,int * fd)17*25da2beaSAndroid Build Coastguard Worker static int test1(struct io_uring *ring, int *fd)
18*25da2beaSAndroid Build Coastguard Worker {
19*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
20*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
21*25da2beaSAndroid Build Coastguard Worker 	int ret, i;
22*25da2beaSAndroid Build Coastguard Worker 
23*25da2beaSAndroid Build Coastguard Worker 	for (i = 0; i < 8; i++) {
24*25da2beaSAndroid Build Coastguard Worker 		sqe = io_uring_get_sqe(ring);
25*25da2beaSAndroid Build Coastguard Worker 		if (!sqe) {
26*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "get sqe failed\n");
27*25da2beaSAndroid Build Coastguard Worker 			return 1;
28*25da2beaSAndroid Build Coastguard Worker 		}
29*25da2beaSAndroid Build Coastguard Worker 
30*25da2beaSAndroid Build Coastguard Worker 		io_uring_prep_poll_add(sqe, fd[0], POLLIN);
31*25da2beaSAndroid Build Coastguard Worker 		sqe->user_data = i + 1;
32*25da2beaSAndroid Build Coastguard Worker 	}
33*25da2beaSAndroid Build Coastguard Worker 
34*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
35*25da2beaSAndroid Build Coastguard Worker 	if (ret < 8) {
36*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "sqe submit failed: %d\n", ret);
37*25da2beaSAndroid Build Coastguard Worker 		return 1;
38*25da2beaSAndroid Build Coastguard Worker 	}
39*25da2beaSAndroid Build Coastguard Worker 
40*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
41*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
42*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "get sqe failed\n");
43*25da2beaSAndroid Build Coastguard Worker 		return 1;
44*25da2beaSAndroid Build Coastguard Worker 	}
45*25da2beaSAndroid Build Coastguard Worker 
46*25da2beaSAndroid Build Coastguard Worker 	/*
47*25da2beaSAndroid Build Coastguard Worker 	 * Mark CANCEL_ALL to cancel all matching the key, and use
48*25da2beaSAndroid Build Coastguard Worker 	 * CANCEL_FD to cancel requests matching the specified fd.
49*25da2beaSAndroid Build Coastguard Worker 	 * This should cancel all the pending poll requests on the pipe
50*25da2beaSAndroid Build Coastguard Worker 	 * input.
51*25da2beaSAndroid Build Coastguard Worker 	 */
52*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_cancel(sqe, 0, IORING_ASYNC_CANCEL_ALL);
53*25da2beaSAndroid Build Coastguard Worker 	sqe->cancel_flags |= IORING_ASYNC_CANCEL_FD;
54*25da2beaSAndroid Build Coastguard Worker 	sqe->fd = fd[0];
55*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 100;
56*25da2beaSAndroid Build Coastguard Worker 
57*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
58*25da2beaSAndroid Build Coastguard Worker 	if (ret < 1) {
59*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "child: sqe submit failed: %d\n", ret);
60*25da2beaSAndroid Build Coastguard Worker 		return 1;
61*25da2beaSAndroid Build Coastguard Worker 	}
62*25da2beaSAndroid Build Coastguard Worker 
63*25da2beaSAndroid Build Coastguard Worker 	for (i = 0; i < 9; i++) {
64*25da2beaSAndroid Build Coastguard Worker 		if (no_cancel_flags)
65*25da2beaSAndroid Build Coastguard Worker 			break;
66*25da2beaSAndroid Build Coastguard Worker 		ret = io_uring_wait_cqe(ring, &cqe);
67*25da2beaSAndroid Build Coastguard Worker 		if (ret) {
68*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "wait=%d\n", ret);
69*25da2beaSAndroid Build Coastguard Worker 			return 1;
70*25da2beaSAndroid Build Coastguard Worker 		}
71*25da2beaSAndroid Build Coastguard Worker 		switch (cqe->user_data) {
72*25da2beaSAndroid Build Coastguard Worker 		case 100:
73*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res == -EINVAL) {
74*25da2beaSAndroid Build Coastguard Worker 				no_cancel_flags = 1;
75*25da2beaSAndroid Build Coastguard Worker 				break;
76*25da2beaSAndroid Build Coastguard Worker 			}
77*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != 8) {
78*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "canceled %d\n", cqe->res);
79*25da2beaSAndroid Build Coastguard Worker 				return 1;
80*25da2beaSAndroid Build Coastguard Worker 			}
81*25da2beaSAndroid Build Coastguard Worker 			break;
82*25da2beaSAndroid Build Coastguard Worker 		case 1 ... 8:
83*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -ECANCELED) {
84*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "poll res %d\n", cqe->res);
85*25da2beaSAndroid Build Coastguard Worker 				return 1;
86*25da2beaSAndroid Build Coastguard Worker 			}
87*25da2beaSAndroid Build Coastguard Worker 			break;
88*25da2beaSAndroid Build Coastguard Worker 		default:
89*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "invalid user_data %lu\n",
90*25da2beaSAndroid Build Coastguard Worker 					(unsigned long) cqe->user_data);
91*25da2beaSAndroid Build Coastguard Worker 			return 1;
92*25da2beaSAndroid Build Coastguard Worker 		}
93*25da2beaSAndroid Build Coastguard Worker 		io_uring_cqe_seen(ring, cqe);
94*25da2beaSAndroid Build Coastguard Worker 	}
95*25da2beaSAndroid Build Coastguard Worker 
96*25da2beaSAndroid Build Coastguard Worker 	return 0;
97*25da2beaSAndroid Build Coastguard Worker }
98*25da2beaSAndroid Build Coastguard Worker 
test2(struct io_uring * ring,int * fd)99*25da2beaSAndroid Build Coastguard Worker static int test2(struct io_uring *ring, int *fd)
100*25da2beaSAndroid Build Coastguard Worker {
101*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
102*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
103*25da2beaSAndroid Build Coastguard Worker 	int ret, i, fd2[2];
104*25da2beaSAndroid Build Coastguard Worker 
105*25da2beaSAndroid Build Coastguard Worker 	if (pipe(fd2) < 0) {
106*25da2beaSAndroid Build Coastguard Worker 		perror("pipe");
107*25da2beaSAndroid Build Coastguard Worker 		return 1;
108*25da2beaSAndroid Build Coastguard Worker 	}
109*25da2beaSAndroid Build Coastguard Worker 
110*25da2beaSAndroid Build Coastguard Worker 	for (i = 0; i < 8; i++) {
111*25da2beaSAndroid Build Coastguard Worker 		sqe = io_uring_get_sqe(ring);
112*25da2beaSAndroid Build Coastguard Worker 		if (!sqe) {
113*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "get sqe failed\n");
114*25da2beaSAndroid Build Coastguard Worker 			goto err;
115*25da2beaSAndroid Build Coastguard Worker 		}
116*25da2beaSAndroid Build Coastguard Worker 
117*25da2beaSAndroid Build Coastguard Worker 		if (!(i & 1))
118*25da2beaSAndroid Build Coastguard Worker 			io_uring_prep_poll_add(sqe, fd[0], POLLIN);
119*25da2beaSAndroid Build Coastguard Worker 		else
120*25da2beaSAndroid Build Coastguard Worker 			io_uring_prep_poll_add(sqe, fd2[0], POLLIN);
121*25da2beaSAndroid Build Coastguard Worker 		sqe->user_data = i & 1;
122*25da2beaSAndroid Build Coastguard Worker 	}
123*25da2beaSAndroid Build Coastguard Worker 
124*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
125*25da2beaSAndroid Build Coastguard Worker 	if (ret < 8) {
126*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "sqe submit failed: %d\n", ret);
127*25da2beaSAndroid Build Coastguard Worker 		goto err;
128*25da2beaSAndroid Build Coastguard Worker 	}
129*25da2beaSAndroid Build Coastguard Worker 
130*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
131*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
132*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "get sqe failed\n");
133*25da2beaSAndroid Build Coastguard Worker 		goto err;
134*25da2beaSAndroid Build Coastguard Worker 	}
135*25da2beaSAndroid Build Coastguard Worker 
136*25da2beaSAndroid Build Coastguard Worker 	/*
137*25da2beaSAndroid Build Coastguard Worker 	 * Mark CANCEL_ALL to cancel all matching the key, and use
138*25da2beaSAndroid Build Coastguard Worker 	 * CANCEL_FD to cancel requests matching the specified fd.
139*25da2beaSAndroid Build Coastguard Worker 	 * This should cancel all the pending poll requests on the pipe
140*25da2beaSAndroid Build Coastguard Worker 	 * input.
141*25da2beaSAndroid Build Coastguard Worker 	 */
142*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_cancel(sqe, 0, IORING_ASYNC_CANCEL_ALL);
143*25da2beaSAndroid Build Coastguard Worker 	sqe->cancel_flags |= IORING_ASYNC_CANCEL_FD;
144*25da2beaSAndroid Build Coastguard Worker 	sqe->fd = fd[0];
145*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 100;
146*25da2beaSAndroid Build Coastguard Worker 
147*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
148*25da2beaSAndroid Build Coastguard Worker 	if (ret < 1) {
149*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "sqe submit failed: %d\n", ret);
150*25da2beaSAndroid Build Coastguard Worker 		goto err;
151*25da2beaSAndroid Build Coastguard Worker 	}
152*25da2beaSAndroid Build Coastguard Worker 
153*25da2beaSAndroid Build Coastguard Worker 	for (i = 0; i < 5; i++) {
154*25da2beaSAndroid Build Coastguard Worker 		ret = io_uring_wait_cqe(ring, &cqe);
155*25da2beaSAndroid Build Coastguard Worker 		if (ret) {
156*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "wait=%d\n", ret);
157*25da2beaSAndroid Build Coastguard Worker 			goto err;
158*25da2beaSAndroid Build Coastguard Worker 		}
159*25da2beaSAndroid Build Coastguard Worker 		switch (cqe->user_data) {
160*25da2beaSAndroid Build Coastguard Worker 		case 100:
161*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != 4) {
162*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "canceled %d\n", cqe->res);
163*25da2beaSAndroid Build Coastguard Worker 				goto err;
164*25da2beaSAndroid Build Coastguard Worker 			}
165*25da2beaSAndroid Build Coastguard Worker 			break;
166*25da2beaSAndroid Build Coastguard Worker 		case 0:
167*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -ECANCELED) {
168*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "poll res %d\n", cqe->res);
169*25da2beaSAndroid Build Coastguard Worker 				goto err;
170*25da2beaSAndroid Build Coastguard Worker 			}
171*25da2beaSAndroid Build Coastguard Worker 			break;
172*25da2beaSAndroid Build Coastguard Worker 		default:
173*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "invalid user_data %lu\n",
174*25da2beaSAndroid Build Coastguard Worker 					(unsigned long) cqe->user_data);
175*25da2beaSAndroid Build Coastguard Worker 			goto err;
176*25da2beaSAndroid Build Coastguard Worker 		}
177*25da2beaSAndroid Build Coastguard Worker 		io_uring_cqe_seen(ring, cqe);
178*25da2beaSAndroid Build Coastguard Worker 	}
179*25da2beaSAndroid Build Coastguard Worker 
180*25da2beaSAndroid Build Coastguard Worker 	usleep(1000);
181*25da2beaSAndroid Build Coastguard Worker 
182*25da2beaSAndroid Build Coastguard Worker 	/*
183*25da2beaSAndroid Build Coastguard Worker 	 * Should not have any pending CQEs now
184*25da2beaSAndroid Build Coastguard Worker 	 */
185*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_peek_cqe(ring, &cqe);
186*25da2beaSAndroid Build Coastguard Worker 	if (!ret) {
187*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Unexpected extra cancel cqe\n");
188*25da2beaSAndroid Build Coastguard Worker 		goto err;
189*25da2beaSAndroid Build Coastguard Worker 	}
190*25da2beaSAndroid Build Coastguard Worker 
191*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
192*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
193*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "get sqe failed\n");
194*25da2beaSAndroid Build Coastguard Worker 		goto err;
195*25da2beaSAndroid Build Coastguard Worker 	}
196*25da2beaSAndroid Build Coastguard Worker 
197*25da2beaSAndroid Build Coastguard Worker 	/*
198*25da2beaSAndroid Build Coastguard Worker 	 * Mark CANCEL_ALL to cancel all matching the key, and use
199*25da2beaSAndroid Build Coastguard Worker 	 * CANCEL_FD to cancel requests matching the specified fd.
200*25da2beaSAndroid Build Coastguard Worker 	 * This should cancel all the pending poll requests on the pipe
201*25da2beaSAndroid Build Coastguard Worker 	 * input.
202*25da2beaSAndroid Build Coastguard Worker 	 */
203*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_cancel(sqe, 0, IORING_ASYNC_CANCEL_ALL);
204*25da2beaSAndroid Build Coastguard Worker 	sqe->cancel_flags |= IORING_ASYNC_CANCEL_FD;
205*25da2beaSAndroid Build Coastguard Worker 	sqe->fd = fd2[0];
206*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 100;
207*25da2beaSAndroid Build Coastguard Worker 
208*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
209*25da2beaSAndroid Build Coastguard Worker 	if (ret < 1) {
210*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "sqe submit failed: %d\n", ret);
211*25da2beaSAndroid Build Coastguard Worker 		goto err;
212*25da2beaSAndroid Build Coastguard Worker 	}
213*25da2beaSAndroid Build Coastguard Worker 
214*25da2beaSAndroid Build Coastguard Worker 	for (i = 0; i < 5; i++) {
215*25da2beaSAndroid Build Coastguard Worker 		ret = io_uring_wait_cqe(ring, &cqe);
216*25da2beaSAndroid Build Coastguard Worker 		if (ret) {
217*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "wait=%d\n", ret);
218*25da2beaSAndroid Build Coastguard Worker 			goto err;
219*25da2beaSAndroid Build Coastguard Worker 		}
220*25da2beaSAndroid Build Coastguard Worker 		switch (cqe->user_data) {
221*25da2beaSAndroid Build Coastguard Worker 		case 100:
222*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != 4) {
223*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "canceled %d\n", cqe->res);
224*25da2beaSAndroid Build Coastguard Worker 				goto err;
225*25da2beaSAndroid Build Coastguard Worker 			}
226*25da2beaSAndroid Build Coastguard Worker 			break;
227*25da2beaSAndroid Build Coastguard Worker 		case 1:
228*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -ECANCELED) {
229*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "poll res %d\n", cqe->res);
230*25da2beaSAndroid Build Coastguard Worker 				goto err;
231*25da2beaSAndroid Build Coastguard Worker 			}
232*25da2beaSAndroid Build Coastguard Worker 			break;
233*25da2beaSAndroid Build Coastguard Worker 		default:
234*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "invalid user_data %lu\n",
235*25da2beaSAndroid Build Coastguard Worker 					(unsigned long) cqe->user_data);
236*25da2beaSAndroid Build Coastguard Worker 			goto err;
237*25da2beaSAndroid Build Coastguard Worker 		}
238*25da2beaSAndroid Build Coastguard Worker 		io_uring_cqe_seen(ring, cqe);
239*25da2beaSAndroid Build Coastguard Worker 	}
240*25da2beaSAndroid Build Coastguard Worker 
241*25da2beaSAndroid Build Coastguard Worker 	close(fd2[0]);
242*25da2beaSAndroid Build Coastguard Worker 	close(fd2[1]);
243*25da2beaSAndroid Build Coastguard Worker 	return 0;
244*25da2beaSAndroid Build Coastguard Worker err:
245*25da2beaSAndroid Build Coastguard Worker 	close(fd2[0]);
246*25da2beaSAndroid Build Coastguard Worker 	close(fd2[1]);
247*25da2beaSAndroid Build Coastguard Worker 	return 1;
248*25da2beaSAndroid Build Coastguard Worker }
249*25da2beaSAndroid Build Coastguard Worker 
test3(struct io_uring * ring,int * fd)250*25da2beaSAndroid Build Coastguard Worker static int test3(struct io_uring *ring, int *fd)
251*25da2beaSAndroid Build Coastguard Worker {
252*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
253*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
254*25da2beaSAndroid Build Coastguard Worker 	int ret, i, fd2[2];
255*25da2beaSAndroid Build Coastguard Worker 
256*25da2beaSAndroid Build Coastguard Worker 	if (pipe(fd2) < 0) {
257*25da2beaSAndroid Build Coastguard Worker 		perror("pipe");
258*25da2beaSAndroid Build Coastguard Worker 		return 1;
259*25da2beaSAndroid Build Coastguard Worker 	}
260*25da2beaSAndroid Build Coastguard Worker 
261*25da2beaSAndroid Build Coastguard Worker 	for (i = 0; i < 8; i++) {
262*25da2beaSAndroid Build Coastguard Worker 		sqe = io_uring_get_sqe(ring);
263*25da2beaSAndroid Build Coastguard Worker 		if (!sqe) {
264*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "get sqe failed\n");
265*25da2beaSAndroid Build Coastguard Worker 			goto err;
266*25da2beaSAndroid Build Coastguard Worker 		}
267*25da2beaSAndroid Build Coastguard Worker 
268*25da2beaSAndroid Build Coastguard Worker 		if (!(i & 1)) {
269*25da2beaSAndroid Build Coastguard Worker 			io_uring_prep_poll_add(sqe, fd[0], POLLIN);
270*25da2beaSAndroid Build Coastguard Worker 			sqe->flags |= IOSQE_ASYNC;
271*25da2beaSAndroid Build Coastguard Worker 		} else
272*25da2beaSAndroid Build Coastguard Worker 			io_uring_prep_poll_add(sqe, fd2[0], POLLIN);
273*25da2beaSAndroid Build Coastguard Worker 		sqe->user_data = i & 1;
274*25da2beaSAndroid Build Coastguard Worker 	}
275*25da2beaSAndroid Build Coastguard Worker 
276*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
277*25da2beaSAndroid Build Coastguard Worker 	if (ret < 8) {
278*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "child: sqe submit failed: %d\n", ret);
279*25da2beaSAndroid Build Coastguard Worker 		goto err;
280*25da2beaSAndroid Build Coastguard Worker 	}
281*25da2beaSAndroid Build Coastguard Worker 
282*25da2beaSAndroid Build Coastguard Worker 	usleep(10000);
283*25da2beaSAndroid Build Coastguard Worker 
284*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
285*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
286*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "get sqe failed\n");
287*25da2beaSAndroid Build Coastguard Worker 		goto err;
288*25da2beaSAndroid Build Coastguard Worker 	}
289*25da2beaSAndroid Build Coastguard Worker 
290*25da2beaSAndroid Build Coastguard Worker 	/*
291*25da2beaSAndroid Build Coastguard Worker 	 * Mark CANCEL_ALL to cancel all matching the key, and use
292*25da2beaSAndroid Build Coastguard Worker 	 * CANCEL_FD to cancel requests matching the specified fd.
293*25da2beaSAndroid Build Coastguard Worker 	 * This should cancel all the pending poll requests on the pipe
294*25da2beaSAndroid Build Coastguard Worker 	 * input.
295*25da2beaSAndroid Build Coastguard Worker 	 */
296*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_cancel(sqe, 0, IORING_ASYNC_CANCEL_ALL);
297*25da2beaSAndroid Build Coastguard Worker 	sqe->cancel_flags |= IORING_ASYNC_CANCEL_ANY;
298*25da2beaSAndroid Build Coastguard Worker 	sqe->fd = 0;
299*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 100;
300*25da2beaSAndroid Build Coastguard Worker 
301*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
302*25da2beaSAndroid Build Coastguard Worker 	if (ret < 1) {
303*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "child: sqe submit failed: %d\n", ret);
304*25da2beaSAndroid Build Coastguard Worker 		goto err;
305*25da2beaSAndroid Build Coastguard Worker 	}
306*25da2beaSAndroid Build Coastguard Worker 
307*25da2beaSAndroid Build Coastguard Worker 	for (i = 0; i < 9; i++) {
308*25da2beaSAndroid Build Coastguard Worker 		ret = io_uring_wait_cqe(ring, &cqe);
309*25da2beaSAndroid Build Coastguard Worker 		if (ret) {
310*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "wait=%d\n", ret);
311*25da2beaSAndroid Build Coastguard Worker 			goto err;
312*25da2beaSAndroid Build Coastguard Worker 		}
313*25da2beaSAndroid Build Coastguard Worker 		switch (cqe->user_data) {
314*25da2beaSAndroid Build Coastguard Worker 		case 100:
315*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != 8) {
316*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "canceled %d\n", cqe->res);
317*25da2beaSAndroid Build Coastguard Worker 				goto err;
318*25da2beaSAndroid Build Coastguard Worker 			}
319*25da2beaSAndroid Build Coastguard Worker 			break;
320*25da2beaSAndroid Build Coastguard Worker 		case 0:
321*25da2beaSAndroid Build Coastguard Worker 		case 1:
322*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -ECANCELED) {
323*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "poll res %d\n", cqe->res);
324*25da2beaSAndroid Build Coastguard Worker 				goto err;
325*25da2beaSAndroid Build Coastguard Worker 			}
326*25da2beaSAndroid Build Coastguard Worker 			break;
327*25da2beaSAndroid Build Coastguard Worker 		default:
328*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "invalid user_data %lu\n",
329*25da2beaSAndroid Build Coastguard Worker 					(unsigned long) cqe->user_data);
330*25da2beaSAndroid Build Coastguard Worker 			goto err;
331*25da2beaSAndroid Build Coastguard Worker 		}
332*25da2beaSAndroid Build Coastguard Worker 		io_uring_cqe_seen(ring, cqe);
333*25da2beaSAndroid Build Coastguard Worker 	}
334*25da2beaSAndroid Build Coastguard Worker 
335*25da2beaSAndroid Build Coastguard Worker 	close(fd2[0]);
336*25da2beaSAndroid Build Coastguard Worker 	close(fd2[1]);
337*25da2beaSAndroid Build Coastguard Worker 	return 0;
338*25da2beaSAndroid Build Coastguard Worker err:
339*25da2beaSAndroid Build Coastguard Worker 	close(fd2[0]);
340*25da2beaSAndroid Build Coastguard Worker 	close(fd2[1]);
341*25da2beaSAndroid Build Coastguard Worker 	return 1;
342*25da2beaSAndroid Build Coastguard Worker }
343*25da2beaSAndroid Build Coastguard Worker 
test4(struct io_uring * ring,int * fd)344*25da2beaSAndroid Build Coastguard Worker static int test4(struct io_uring *ring, int *fd)
345*25da2beaSAndroid Build Coastguard Worker {
346*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
347*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
348*25da2beaSAndroid Build Coastguard Worker 	char buffer[32];
349*25da2beaSAndroid Build Coastguard Worker 	int ret, i;
350*25da2beaSAndroid Build Coastguard Worker 
351*25da2beaSAndroid Build Coastguard Worker 	for (i = 0; i < 8; i++) {
352*25da2beaSAndroid Build Coastguard Worker 		sqe = io_uring_get_sqe(ring);
353*25da2beaSAndroid Build Coastguard Worker 		if (!sqe) {
354*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "get sqe failed\n");
355*25da2beaSAndroid Build Coastguard Worker 			goto err;
356*25da2beaSAndroid Build Coastguard Worker 		}
357*25da2beaSAndroid Build Coastguard Worker 
358*25da2beaSAndroid Build Coastguard Worker 		io_uring_prep_read(sqe, fd[0], &buffer, sizeof(buffer), 0);
359*25da2beaSAndroid Build Coastguard Worker 		sqe->flags |= IOSQE_ASYNC;
360*25da2beaSAndroid Build Coastguard Worker 		sqe->user_data = i + 1;
361*25da2beaSAndroid Build Coastguard Worker 	}
362*25da2beaSAndroid Build Coastguard Worker 
363*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
364*25da2beaSAndroid Build Coastguard Worker 	if (ret < 8) {
365*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "child: sqe submit failed: %d\n", ret);
366*25da2beaSAndroid Build Coastguard Worker 		goto err;
367*25da2beaSAndroid Build Coastguard Worker 	}
368*25da2beaSAndroid Build Coastguard Worker 
369*25da2beaSAndroid Build Coastguard Worker 	usleep(10000);
370*25da2beaSAndroid Build Coastguard Worker 
371*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
372*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
373*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "get sqe failed\n");
374*25da2beaSAndroid Build Coastguard Worker 		goto err;
375*25da2beaSAndroid Build Coastguard Worker 	}
376*25da2beaSAndroid Build Coastguard Worker 
377*25da2beaSAndroid Build Coastguard Worker 	/*
378*25da2beaSAndroid Build Coastguard Worker 	 * Mark CANCEL_ALL to cancel all matching the key, and use
379*25da2beaSAndroid Build Coastguard Worker 	 * CANCEL_FD to cancel requests matching the specified fd.
380*25da2beaSAndroid Build Coastguard Worker 	 * This should cancel all the pending poll requests on the pipe
381*25da2beaSAndroid Build Coastguard Worker 	 * input.
382*25da2beaSAndroid Build Coastguard Worker 	 */
383*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_cancel(sqe, 0, IORING_ASYNC_CANCEL_ALL);
384*25da2beaSAndroid Build Coastguard Worker 	sqe->cancel_flags |= IORING_ASYNC_CANCEL_ANY;
385*25da2beaSAndroid Build Coastguard Worker 	sqe->fd = 0;
386*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 100;
387*25da2beaSAndroid Build Coastguard Worker 
388*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
389*25da2beaSAndroid Build Coastguard Worker 	if (ret < 1) {
390*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "child: sqe submit failed: %d\n", ret);
391*25da2beaSAndroid Build Coastguard Worker 		goto err;
392*25da2beaSAndroid Build Coastguard Worker 	}
393*25da2beaSAndroid Build Coastguard Worker 
394*25da2beaSAndroid Build Coastguard Worker 	for (i = 0; i < 9; i++) {
395*25da2beaSAndroid Build Coastguard Worker 		ret = io_uring_wait_cqe(ring, &cqe);
396*25da2beaSAndroid Build Coastguard Worker 		if (ret) {
397*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "wait=%d\n", ret);
398*25da2beaSAndroid Build Coastguard Worker 			goto err;
399*25da2beaSAndroid Build Coastguard Worker 		}
400*25da2beaSAndroid Build Coastguard Worker 		switch (cqe->user_data) {
401*25da2beaSAndroid Build Coastguard Worker 		case 100:
402*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != 8) {
403*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "canceled %d\n", cqe->res);
404*25da2beaSAndroid Build Coastguard Worker 				goto err;
405*25da2beaSAndroid Build Coastguard Worker 			}
406*25da2beaSAndroid Build Coastguard Worker 			break;
407*25da2beaSAndroid Build Coastguard Worker 		case 1 ... 8:
408*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -ECANCELED) {
409*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "poll res %d\n", cqe->res);
410*25da2beaSAndroid Build Coastguard Worker 				goto err;
411*25da2beaSAndroid Build Coastguard Worker 			}
412*25da2beaSAndroid Build Coastguard Worker 			break;
413*25da2beaSAndroid Build Coastguard Worker 		default:
414*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "invalid user_data %lu\n",
415*25da2beaSAndroid Build Coastguard Worker 					(unsigned long) cqe->user_data);
416*25da2beaSAndroid Build Coastguard Worker 			goto err;
417*25da2beaSAndroid Build Coastguard Worker 		}
418*25da2beaSAndroid Build Coastguard Worker 		io_uring_cqe_seen(ring, cqe);
419*25da2beaSAndroid Build Coastguard Worker 	}
420*25da2beaSAndroid Build Coastguard Worker 
421*25da2beaSAndroid Build Coastguard Worker 	return 0;
422*25da2beaSAndroid Build Coastguard Worker err:
423*25da2beaSAndroid Build Coastguard Worker 	return 1;
424*25da2beaSAndroid Build Coastguard Worker }
425*25da2beaSAndroid Build Coastguard Worker 
main(int argc,char * argv[])426*25da2beaSAndroid Build Coastguard Worker int main(int argc, char *argv[])
427*25da2beaSAndroid Build Coastguard Worker {
428*25da2beaSAndroid Build Coastguard Worker 	struct io_uring ring;
429*25da2beaSAndroid Build Coastguard Worker 	int ret, fd[2];
430*25da2beaSAndroid Build Coastguard Worker 
431*25da2beaSAndroid Build Coastguard Worker 	if (argc > 1)
432*25da2beaSAndroid Build Coastguard Worker 		return 0;
433*25da2beaSAndroid Build Coastguard Worker 
434*25da2beaSAndroid Build Coastguard Worker 	if (pipe(fd) < 0) {
435*25da2beaSAndroid Build Coastguard Worker 		perror("pipe");
436*25da2beaSAndroid Build Coastguard Worker 		return 1;
437*25da2beaSAndroid Build Coastguard Worker 	}
438*25da2beaSAndroid Build Coastguard Worker 
439*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_queue_init(8, &ring, 0);
440*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
441*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "ring setup failed: %d\n", ret);
442*25da2beaSAndroid Build Coastguard Worker 		return 1;
443*25da2beaSAndroid Build Coastguard Worker 	}
444*25da2beaSAndroid Build Coastguard Worker 
445*25da2beaSAndroid Build Coastguard Worker 	ret = test1(&ring, fd);
446*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
447*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "test1 failed\n");
448*25da2beaSAndroid Build Coastguard Worker 		return ret;
449*25da2beaSAndroid Build Coastguard Worker 	}
450*25da2beaSAndroid Build Coastguard Worker 	if (no_cancel_flags)
451*25da2beaSAndroid Build Coastguard Worker 		return 0;
452*25da2beaSAndroid Build Coastguard Worker 
453*25da2beaSAndroid Build Coastguard Worker 	ret = test2(&ring, fd);
454*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
455*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "test2 failed\n");
456*25da2beaSAndroid Build Coastguard Worker 		return ret;
457*25da2beaSAndroid Build Coastguard Worker 	}
458*25da2beaSAndroid Build Coastguard Worker 
459*25da2beaSAndroid Build Coastguard Worker 	ret = test3(&ring, fd);
460*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
461*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "test3 failed\n");
462*25da2beaSAndroid Build Coastguard Worker 		return ret;
463*25da2beaSAndroid Build Coastguard Worker 	}
464*25da2beaSAndroid Build Coastguard Worker 
465*25da2beaSAndroid Build Coastguard Worker 	ret = test4(&ring, fd);
466*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
467*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "test4 failed\n");
468*25da2beaSAndroid Build Coastguard Worker 		return ret;
469*25da2beaSAndroid Build Coastguard Worker 	}
470*25da2beaSAndroid Build Coastguard Worker 
471*25da2beaSAndroid Build Coastguard Worker 	return 0;
472*25da2beaSAndroid Build Coastguard Worker }
473