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