1*25da2beaSAndroid Build Coastguard Worker /* SPDX-License-Identifier: MIT */
2*25da2beaSAndroid Build Coastguard Worker /*
3*25da2beaSAndroid Build Coastguard Worker * Simple test case using the socket op
4*25da2beaSAndroid Build Coastguard Worker */
5*25da2beaSAndroid Build Coastguard Worker #include <errno.h>
6*25da2beaSAndroid Build Coastguard Worker #include <stdio.h>
7*25da2beaSAndroid Build Coastguard Worker #include <stdlib.h>
8*25da2beaSAndroid Build Coastguard Worker #include <string.h>
9*25da2beaSAndroid Build Coastguard Worker #include <unistd.h>
10*25da2beaSAndroid Build Coastguard Worker #include <arpa/inet.h>
11*25da2beaSAndroid Build Coastguard Worker #include <sys/types.h>
12*25da2beaSAndroid Build Coastguard Worker #include <sys/socket.h>
13*25da2beaSAndroid Build Coastguard Worker #include <pthread.h>
14*25da2beaSAndroid Build Coastguard Worker
15*25da2beaSAndroid Build Coastguard Worker #include "liburing.h"
16*25da2beaSAndroid Build Coastguard Worker #include "helpers.h"
17*25da2beaSAndroid Build Coastguard Worker
18*25da2beaSAndroid Build Coastguard Worker static char str[] = "This is a test of send and recv over io_uring!";
19*25da2beaSAndroid Build Coastguard Worker
20*25da2beaSAndroid Build Coastguard Worker #define MAX_MSG 128
21*25da2beaSAndroid Build Coastguard Worker
22*25da2beaSAndroid Build Coastguard Worker #define PORT 10202
23*25da2beaSAndroid Build Coastguard Worker #define HOST "127.0.0.1"
24*25da2beaSAndroid Build Coastguard Worker
25*25da2beaSAndroid Build Coastguard Worker static int no_socket;
26*25da2beaSAndroid Build Coastguard Worker
recv_prep(struct io_uring * ring,struct iovec * iov,int * sock,int registerfiles)27*25da2beaSAndroid Build Coastguard Worker static int recv_prep(struct io_uring *ring, struct iovec *iov, int *sock,
28*25da2beaSAndroid Build Coastguard Worker int registerfiles)
29*25da2beaSAndroid Build Coastguard Worker {
30*25da2beaSAndroid Build Coastguard Worker struct sockaddr_in saddr;
31*25da2beaSAndroid Build Coastguard Worker struct io_uring_sqe *sqe;
32*25da2beaSAndroid Build Coastguard Worker int sockfd, ret, val, use_fd;
33*25da2beaSAndroid Build Coastguard Worker
34*25da2beaSAndroid Build Coastguard Worker memset(&saddr, 0, sizeof(saddr));
35*25da2beaSAndroid Build Coastguard Worker saddr.sin_family = AF_INET;
36*25da2beaSAndroid Build Coastguard Worker saddr.sin_addr.s_addr = htonl(INADDR_ANY);
37*25da2beaSAndroid Build Coastguard Worker saddr.sin_port = htons(PORT);
38*25da2beaSAndroid Build Coastguard Worker
39*25da2beaSAndroid Build Coastguard Worker sockfd = socket(AF_INET, SOCK_DGRAM, 0);
40*25da2beaSAndroid Build Coastguard Worker if (sockfd < 0) {
41*25da2beaSAndroid Build Coastguard Worker perror("socket");
42*25da2beaSAndroid Build Coastguard Worker return 1;
43*25da2beaSAndroid Build Coastguard Worker }
44*25da2beaSAndroid Build Coastguard Worker
45*25da2beaSAndroid Build Coastguard Worker val = 1;
46*25da2beaSAndroid Build Coastguard Worker setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
47*25da2beaSAndroid Build Coastguard Worker
48*25da2beaSAndroid Build Coastguard Worker ret = bind(sockfd, (struct sockaddr *)&saddr, sizeof(saddr));
49*25da2beaSAndroid Build Coastguard Worker if (ret < 0) {
50*25da2beaSAndroid Build Coastguard Worker perror("bind");
51*25da2beaSAndroid Build Coastguard Worker goto err;
52*25da2beaSAndroid Build Coastguard Worker }
53*25da2beaSAndroid Build Coastguard Worker
54*25da2beaSAndroid Build Coastguard Worker if (registerfiles) {
55*25da2beaSAndroid Build Coastguard Worker ret = io_uring_register_files(ring, &sockfd, 1);
56*25da2beaSAndroid Build Coastguard Worker if (ret) {
57*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "file reg failed\n");
58*25da2beaSAndroid Build Coastguard Worker goto err;
59*25da2beaSAndroid Build Coastguard Worker }
60*25da2beaSAndroid Build Coastguard Worker use_fd = 0;
61*25da2beaSAndroid Build Coastguard Worker } else {
62*25da2beaSAndroid Build Coastguard Worker use_fd = sockfd;
63*25da2beaSAndroid Build Coastguard Worker }
64*25da2beaSAndroid Build Coastguard Worker
65*25da2beaSAndroid Build Coastguard Worker sqe = io_uring_get_sqe(ring);
66*25da2beaSAndroid Build Coastguard Worker io_uring_prep_recv(sqe, use_fd, iov->iov_base, iov->iov_len, 0);
67*25da2beaSAndroid Build Coastguard Worker if (registerfiles)
68*25da2beaSAndroid Build Coastguard Worker sqe->flags |= IOSQE_FIXED_FILE;
69*25da2beaSAndroid Build Coastguard Worker sqe->user_data = 2;
70*25da2beaSAndroid Build Coastguard Worker
71*25da2beaSAndroid Build Coastguard Worker ret = io_uring_submit(ring);
72*25da2beaSAndroid Build Coastguard Worker if (ret <= 0) {
73*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "submit failed: %d\n", ret);
74*25da2beaSAndroid Build Coastguard Worker goto err;
75*25da2beaSAndroid Build Coastguard Worker }
76*25da2beaSAndroid Build Coastguard Worker
77*25da2beaSAndroid Build Coastguard Worker *sock = sockfd;
78*25da2beaSAndroid Build Coastguard Worker return 0;
79*25da2beaSAndroid Build Coastguard Worker err:
80*25da2beaSAndroid Build Coastguard Worker close(sockfd);
81*25da2beaSAndroid Build Coastguard Worker return 1;
82*25da2beaSAndroid Build Coastguard Worker }
83*25da2beaSAndroid Build Coastguard Worker
do_recv(struct io_uring * ring,struct iovec * iov)84*25da2beaSAndroid Build Coastguard Worker static int do_recv(struct io_uring *ring, struct iovec *iov)
85*25da2beaSAndroid Build Coastguard Worker {
86*25da2beaSAndroid Build Coastguard Worker struct io_uring_cqe *cqe;
87*25da2beaSAndroid Build Coastguard Worker int ret;
88*25da2beaSAndroid Build Coastguard Worker
89*25da2beaSAndroid Build Coastguard Worker ret = io_uring_wait_cqe(ring, &cqe);
90*25da2beaSAndroid Build Coastguard Worker if (ret) {
91*25da2beaSAndroid Build Coastguard Worker fprintf(stdout, "wait_cqe: %d\n", ret);
92*25da2beaSAndroid Build Coastguard Worker goto err;
93*25da2beaSAndroid Build Coastguard Worker }
94*25da2beaSAndroid Build Coastguard Worker if (cqe->res == -EINVAL) {
95*25da2beaSAndroid Build Coastguard Worker fprintf(stdout, "recv not supported, skipping\n");
96*25da2beaSAndroid Build Coastguard Worker return 0;
97*25da2beaSAndroid Build Coastguard Worker }
98*25da2beaSAndroid Build Coastguard Worker if (cqe->res < 0) {
99*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "failed cqe: %d\n", cqe->res);
100*25da2beaSAndroid Build Coastguard Worker goto err;
101*25da2beaSAndroid Build Coastguard Worker }
102*25da2beaSAndroid Build Coastguard Worker
103*25da2beaSAndroid Build Coastguard Worker if (cqe->res -1 != strlen(str)) {
104*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "got wrong length: %d/%d\n", cqe->res,
105*25da2beaSAndroid Build Coastguard Worker (int) strlen(str) + 1);
106*25da2beaSAndroid Build Coastguard Worker goto err;
107*25da2beaSAndroid Build Coastguard Worker }
108*25da2beaSAndroid Build Coastguard Worker
109*25da2beaSAndroid Build Coastguard Worker if (strcmp(str, iov->iov_base)) {
110*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "string mismatch\n");
111*25da2beaSAndroid Build Coastguard Worker goto err;
112*25da2beaSAndroid Build Coastguard Worker }
113*25da2beaSAndroid Build Coastguard Worker
114*25da2beaSAndroid Build Coastguard Worker return 0;
115*25da2beaSAndroid Build Coastguard Worker err:
116*25da2beaSAndroid Build Coastguard Worker return 1;
117*25da2beaSAndroid Build Coastguard Worker }
118*25da2beaSAndroid Build Coastguard Worker
119*25da2beaSAndroid Build Coastguard Worker struct recv_data {
120*25da2beaSAndroid Build Coastguard Worker pthread_mutex_t mutex;
121*25da2beaSAndroid Build Coastguard Worker int use_sqthread;
122*25da2beaSAndroid Build Coastguard Worker int registerfiles;
123*25da2beaSAndroid Build Coastguard Worker };
124*25da2beaSAndroid Build Coastguard Worker
recv_fn(void * data)125*25da2beaSAndroid Build Coastguard Worker static void *recv_fn(void *data)
126*25da2beaSAndroid Build Coastguard Worker {
127*25da2beaSAndroid Build Coastguard Worker struct recv_data *rd = data;
128*25da2beaSAndroid Build Coastguard Worker char buf[MAX_MSG + 1];
129*25da2beaSAndroid Build Coastguard Worker struct iovec iov = {
130*25da2beaSAndroid Build Coastguard Worker .iov_base = buf,
131*25da2beaSAndroid Build Coastguard Worker .iov_len = sizeof(buf) - 1,
132*25da2beaSAndroid Build Coastguard Worker };
133*25da2beaSAndroid Build Coastguard Worker struct io_uring_params p = { };
134*25da2beaSAndroid Build Coastguard Worker struct io_uring ring;
135*25da2beaSAndroid Build Coastguard Worker int ret, sock;
136*25da2beaSAndroid Build Coastguard Worker
137*25da2beaSAndroid Build Coastguard Worker if (rd->use_sqthread)
138*25da2beaSAndroid Build Coastguard Worker p.flags = IORING_SETUP_SQPOLL;
139*25da2beaSAndroid Build Coastguard Worker ret = t_create_ring_params(1, &ring, &p);
140*25da2beaSAndroid Build Coastguard Worker if (ret == T_SETUP_SKIP) {
141*25da2beaSAndroid Build Coastguard Worker pthread_mutex_unlock(&rd->mutex);
142*25da2beaSAndroid Build Coastguard Worker ret = 0;
143*25da2beaSAndroid Build Coastguard Worker goto err;
144*25da2beaSAndroid Build Coastguard Worker } else if (ret < 0) {
145*25da2beaSAndroid Build Coastguard Worker pthread_mutex_unlock(&rd->mutex);
146*25da2beaSAndroid Build Coastguard Worker goto err;
147*25da2beaSAndroid Build Coastguard Worker }
148*25da2beaSAndroid Build Coastguard Worker
149*25da2beaSAndroid Build Coastguard Worker if (rd->use_sqthread && !rd->registerfiles) {
150*25da2beaSAndroid Build Coastguard Worker if (!(p.features & IORING_FEAT_SQPOLL_NONFIXED)) {
151*25da2beaSAndroid Build Coastguard Worker fprintf(stdout, "Non-registered SQPOLL not available, skipping\n");
152*25da2beaSAndroid Build Coastguard Worker pthread_mutex_unlock(&rd->mutex);
153*25da2beaSAndroid Build Coastguard Worker goto err;
154*25da2beaSAndroid Build Coastguard Worker }
155*25da2beaSAndroid Build Coastguard Worker }
156*25da2beaSAndroid Build Coastguard Worker
157*25da2beaSAndroid Build Coastguard Worker ret = recv_prep(&ring, &iov, &sock, rd->registerfiles);
158*25da2beaSAndroid Build Coastguard Worker if (ret) {
159*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "recv_prep failed: %d\n", ret);
160*25da2beaSAndroid Build Coastguard Worker goto err;
161*25da2beaSAndroid Build Coastguard Worker }
162*25da2beaSAndroid Build Coastguard Worker pthread_mutex_unlock(&rd->mutex);
163*25da2beaSAndroid Build Coastguard Worker ret = do_recv(&ring, &iov);
164*25da2beaSAndroid Build Coastguard Worker
165*25da2beaSAndroid Build Coastguard Worker close(sock);
166*25da2beaSAndroid Build Coastguard Worker io_uring_queue_exit(&ring);
167*25da2beaSAndroid Build Coastguard Worker err:
168*25da2beaSAndroid Build Coastguard Worker return (void *)(intptr_t)ret;
169*25da2beaSAndroid Build Coastguard Worker }
170*25da2beaSAndroid Build Coastguard Worker
fallback_send(struct io_uring * ring,struct sockaddr_in * saddr)171*25da2beaSAndroid Build Coastguard Worker static int fallback_send(struct io_uring *ring, struct sockaddr_in *saddr)
172*25da2beaSAndroid Build Coastguard Worker {
173*25da2beaSAndroid Build Coastguard Worker struct iovec iov = {
174*25da2beaSAndroid Build Coastguard Worker .iov_base = str,
175*25da2beaSAndroid Build Coastguard Worker .iov_len = sizeof(str),
176*25da2beaSAndroid Build Coastguard Worker };
177*25da2beaSAndroid Build Coastguard Worker struct io_uring_cqe *cqe;
178*25da2beaSAndroid Build Coastguard Worker struct io_uring_sqe *sqe;
179*25da2beaSAndroid Build Coastguard Worker int sockfd, ret;
180*25da2beaSAndroid Build Coastguard Worker
181*25da2beaSAndroid Build Coastguard Worker sockfd = socket(AF_INET, SOCK_DGRAM, 0);
182*25da2beaSAndroid Build Coastguard Worker if (sockfd < 0) {
183*25da2beaSAndroid Build Coastguard Worker perror("socket");
184*25da2beaSAndroid Build Coastguard Worker return 1;
185*25da2beaSAndroid Build Coastguard Worker }
186*25da2beaSAndroid Build Coastguard Worker
187*25da2beaSAndroid Build Coastguard Worker ret = connect(sockfd, (struct sockaddr *)saddr, sizeof(*saddr));
188*25da2beaSAndroid Build Coastguard Worker if (ret < 0) {
189*25da2beaSAndroid Build Coastguard Worker perror("connect");
190*25da2beaSAndroid Build Coastguard Worker return 1;
191*25da2beaSAndroid Build Coastguard Worker }
192*25da2beaSAndroid Build Coastguard Worker
193*25da2beaSAndroid Build Coastguard Worker sqe = io_uring_get_sqe(ring);
194*25da2beaSAndroid Build Coastguard Worker io_uring_prep_send(sqe, sockfd, iov.iov_base, iov.iov_len, 0);
195*25da2beaSAndroid Build Coastguard Worker sqe->user_data = 1;
196*25da2beaSAndroid Build Coastguard Worker
197*25da2beaSAndroid Build Coastguard Worker ret = io_uring_submit(ring);
198*25da2beaSAndroid Build Coastguard Worker if (ret <= 0) {
199*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "submit failed: %d\n", ret);
200*25da2beaSAndroid Build Coastguard Worker goto err;
201*25da2beaSAndroid Build Coastguard Worker }
202*25da2beaSAndroid Build Coastguard Worker
203*25da2beaSAndroid Build Coastguard Worker ret = io_uring_wait_cqe(ring, &cqe);
204*25da2beaSAndroid Build Coastguard Worker if (cqe->res == -EINVAL) {
205*25da2beaSAndroid Build Coastguard Worker fprintf(stdout, "send not supported, skipping\n");
206*25da2beaSAndroid Build Coastguard Worker close(sockfd);
207*25da2beaSAndroid Build Coastguard Worker return 0;
208*25da2beaSAndroid Build Coastguard Worker }
209*25da2beaSAndroid Build Coastguard Worker if (cqe->res != iov.iov_len) {
210*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "failed cqe: %d\n", cqe->res);
211*25da2beaSAndroid Build Coastguard Worker goto err;
212*25da2beaSAndroid Build Coastguard Worker }
213*25da2beaSAndroid Build Coastguard Worker
214*25da2beaSAndroid Build Coastguard Worker close(sockfd);
215*25da2beaSAndroid Build Coastguard Worker return 0;
216*25da2beaSAndroid Build Coastguard Worker err:
217*25da2beaSAndroid Build Coastguard Worker close(sockfd);
218*25da2beaSAndroid Build Coastguard Worker return 1;
219*25da2beaSAndroid Build Coastguard Worker }
220*25da2beaSAndroid Build Coastguard Worker
do_send(int socket_direct,int alloc)221*25da2beaSAndroid Build Coastguard Worker static int do_send(int socket_direct, int alloc)
222*25da2beaSAndroid Build Coastguard Worker {
223*25da2beaSAndroid Build Coastguard Worker struct sockaddr_in saddr;
224*25da2beaSAndroid Build Coastguard Worker struct iovec iov = {
225*25da2beaSAndroid Build Coastguard Worker .iov_base = str,
226*25da2beaSAndroid Build Coastguard Worker .iov_len = sizeof(str),
227*25da2beaSAndroid Build Coastguard Worker };
228*25da2beaSAndroid Build Coastguard Worker struct io_uring ring;
229*25da2beaSAndroid Build Coastguard Worker struct io_uring_cqe *cqe;
230*25da2beaSAndroid Build Coastguard Worker struct io_uring_sqe *sqe;
231*25da2beaSAndroid Build Coastguard Worker int sockfd, ret, fd = -1;
232*25da2beaSAndroid Build Coastguard Worker
233*25da2beaSAndroid Build Coastguard Worker ret = io_uring_queue_init(1, &ring, 0);
234*25da2beaSAndroid Build Coastguard Worker if (ret) {
235*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "queue init failed: %d\n", ret);
236*25da2beaSAndroid Build Coastguard Worker return 1;
237*25da2beaSAndroid Build Coastguard Worker }
238*25da2beaSAndroid Build Coastguard Worker
239*25da2beaSAndroid Build Coastguard Worker if (socket_direct) {
240*25da2beaSAndroid Build Coastguard Worker ret = io_uring_register_files(&ring, &fd, 1);
241*25da2beaSAndroid Build Coastguard Worker if (ret) {
242*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "file register %d\n", ret);
243*25da2beaSAndroid Build Coastguard Worker return 1;
244*25da2beaSAndroid Build Coastguard Worker }
245*25da2beaSAndroid Build Coastguard Worker }
246*25da2beaSAndroid Build Coastguard Worker
247*25da2beaSAndroid Build Coastguard Worker memset(&saddr, 0, sizeof(saddr));
248*25da2beaSAndroid Build Coastguard Worker saddr.sin_family = AF_INET;
249*25da2beaSAndroid Build Coastguard Worker saddr.sin_port = htons(PORT);
250*25da2beaSAndroid Build Coastguard Worker inet_pton(AF_INET, HOST, &saddr.sin_addr);
251*25da2beaSAndroid Build Coastguard Worker
252*25da2beaSAndroid Build Coastguard Worker sqe = io_uring_get_sqe(&ring);
253*25da2beaSAndroid Build Coastguard Worker if (socket_direct) {
254*25da2beaSAndroid Build Coastguard Worker unsigned file_index = 0;
255*25da2beaSAndroid Build Coastguard Worker if (alloc)
256*25da2beaSAndroid Build Coastguard Worker file_index = IORING_FILE_INDEX_ALLOC - 1;
257*25da2beaSAndroid Build Coastguard Worker io_uring_prep_socket_direct(sqe, AF_INET, SOCK_DGRAM, 0,
258*25da2beaSAndroid Build Coastguard Worker file_index, 0);
259*25da2beaSAndroid Build Coastguard Worker } else {
260*25da2beaSAndroid Build Coastguard Worker io_uring_prep_socket(sqe, AF_INET, SOCK_DGRAM, 0, 0);
261*25da2beaSAndroid Build Coastguard Worker }
262*25da2beaSAndroid Build Coastguard Worker ret = io_uring_submit(&ring);
263*25da2beaSAndroid Build Coastguard Worker if (ret != 1) {
264*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "socket submit: %d\n", ret);
265*25da2beaSAndroid Build Coastguard Worker return 1;
266*25da2beaSAndroid Build Coastguard Worker }
267*25da2beaSAndroid Build Coastguard Worker ret = io_uring_wait_cqe(&ring, &cqe);
268*25da2beaSAndroid Build Coastguard Worker if (ret) {
269*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "wait_cqe: %d\n", ret);
270*25da2beaSAndroid Build Coastguard Worker return 1;
271*25da2beaSAndroid Build Coastguard Worker }
272*25da2beaSAndroid Build Coastguard Worker if (cqe->res < 0) {
273*25da2beaSAndroid Build Coastguard Worker if (cqe->res == -EINVAL) {
274*25da2beaSAndroid Build Coastguard Worker fprintf(stdout, "No socket support, skipping\n");
275*25da2beaSAndroid Build Coastguard Worker no_socket = 1;
276*25da2beaSAndroid Build Coastguard Worker io_uring_cqe_seen(&ring, cqe);
277*25da2beaSAndroid Build Coastguard Worker return fallback_send(&ring, &saddr);
278*25da2beaSAndroid Build Coastguard Worker }
279*25da2beaSAndroid Build Coastguard Worker
280*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "socket res: %d\n", ret);
281*25da2beaSAndroid Build Coastguard Worker return 1;
282*25da2beaSAndroid Build Coastguard Worker }
283*25da2beaSAndroid Build Coastguard Worker
284*25da2beaSAndroid Build Coastguard Worker sockfd = cqe->res;
285*25da2beaSAndroid Build Coastguard Worker if (socket_direct && !alloc)
286*25da2beaSAndroid Build Coastguard Worker sockfd = 0;
287*25da2beaSAndroid Build Coastguard Worker io_uring_cqe_seen(&ring, cqe);
288*25da2beaSAndroid Build Coastguard Worker
289*25da2beaSAndroid Build Coastguard Worker sqe = io_uring_get_sqe(&ring);
290*25da2beaSAndroid Build Coastguard Worker io_uring_prep_connect(sqe, sockfd, (struct sockaddr *) &saddr,
291*25da2beaSAndroid Build Coastguard Worker sizeof(saddr));
292*25da2beaSAndroid Build Coastguard Worker if (socket_direct)
293*25da2beaSAndroid Build Coastguard Worker sqe->flags |= IOSQE_FIXED_FILE;
294*25da2beaSAndroid Build Coastguard Worker ret = io_uring_submit(&ring);
295*25da2beaSAndroid Build Coastguard Worker if (ret != 1) {
296*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "connect submit: %d\n", ret);
297*25da2beaSAndroid Build Coastguard Worker return 1;
298*25da2beaSAndroid Build Coastguard Worker }
299*25da2beaSAndroid Build Coastguard Worker ret = io_uring_wait_cqe(&ring, &cqe);
300*25da2beaSAndroid Build Coastguard Worker if (ret) {
301*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "wait_cqe: %d\n", ret);
302*25da2beaSAndroid Build Coastguard Worker return 1;
303*25da2beaSAndroid Build Coastguard Worker }
304*25da2beaSAndroid Build Coastguard Worker if (cqe->res < 0) {
305*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "connect res: %d\n", cqe->res);
306*25da2beaSAndroid Build Coastguard Worker return 1;
307*25da2beaSAndroid Build Coastguard Worker }
308*25da2beaSAndroid Build Coastguard Worker io_uring_cqe_seen(&ring, cqe);
309*25da2beaSAndroid Build Coastguard Worker
310*25da2beaSAndroid Build Coastguard Worker sqe = io_uring_get_sqe(&ring);
311*25da2beaSAndroid Build Coastguard Worker io_uring_prep_send(sqe, sockfd, iov.iov_base, iov.iov_len, 0);
312*25da2beaSAndroid Build Coastguard Worker sqe->user_data = 1;
313*25da2beaSAndroid Build Coastguard Worker if (socket_direct)
314*25da2beaSAndroid Build Coastguard Worker sqe->flags |= IOSQE_FIXED_FILE;
315*25da2beaSAndroid Build Coastguard Worker
316*25da2beaSAndroid Build Coastguard Worker ret = io_uring_submit(&ring);
317*25da2beaSAndroid Build Coastguard Worker if (ret <= 0) {
318*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "submit failed: %d\n", ret);
319*25da2beaSAndroid Build Coastguard Worker goto err;
320*25da2beaSAndroid Build Coastguard Worker }
321*25da2beaSAndroid Build Coastguard Worker
322*25da2beaSAndroid Build Coastguard Worker ret = io_uring_wait_cqe(&ring, &cqe);
323*25da2beaSAndroid Build Coastguard Worker if (cqe->res == -EINVAL) {
324*25da2beaSAndroid Build Coastguard Worker fprintf(stdout, "send not supported, skipping\n");
325*25da2beaSAndroid Build Coastguard Worker close(sockfd);
326*25da2beaSAndroid Build Coastguard Worker return 0;
327*25da2beaSAndroid Build Coastguard Worker }
328*25da2beaSAndroid Build Coastguard Worker if (cqe->res != iov.iov_len) {
329*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "failed cqe: %d\n", cqe->res);
330*25da2beaSAndroid Build Coastguard Worker goto err;
331*25da2beaSAndroid Build Coastguard Worker }
332*25da2beaSAndroid Build Coastguard Worker
333*25da2beaSAndroid Build Coastguard Worker close(sockfd);
334*25da2beaSAndroid Build Coastguard Worker return 0;
335*25da2beaSAndroid Build Coastguard Worker err:
336*25da2beaSAndroid Build Coastguard Worker close(sockfd);
337*25da2beaSAndroid Build Coastguard Worker return 1;
338*25da2beaSAndroid Build Coastguard Worker }
339*25da2beaSAndroid Build Coastguard Worker
test(int use_sqthread,int regfiles,int socket_direct,int alloc)340*25da2beaSAndroid Build Coastguard Worker static int test(int use_sqthread, int regfiles, int socket_direct, int alloc)
341*25da2beaSAndroid Build Coastguard Worker {
342*25da2beaSAndroid Build Coastguard Worker pthread_mutexattr_t attr;
343*25da2beaSAndroid Build Coastguard Worker pthread_t recv_thread;
344*25da2beaSAndroid Build Coastguard Worker struct recv_data rd;
345*25da2beaSAndroid Build Coastguard Worker int ret;
346*25da2beaSAndroid Build Coastguard Worker void *retval;
347*25da2beaSAndroid Build Coastguard Worker
348*25da2beaSAndroid Build Coastguard Worker pthread_mutexattr_init(&attr);
349*25da2beaSAndroid Build Coastguard Worker pthread_mutexattr_setpshared(&attr, 1);
350*25da2beaSAndroid Build Coastguard Worker pthread_mutex_init(&rd.mutex, &attr);
351*25da2beaSAndroid Build Coastguard Worker pthread_mutex_lock(&rd.mutex);
352*25da2beaSAndroid Build Coastguard Worker rd.use_sqthread = use_sqthread;
353*25da2beaSAndroid Build Coastguard Worker rd.registerfiles = regfiles;
354*25da2beaSAndroid Build Coastguard Worker
355*25da2beaSAndroid Build Coastguard Worker ret = pthread_create(&recv_thread, NULL, recv_fn, &rd);
356*25da2beaSAndroid Build Coastguard Worker if (ret) {
357*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "Thread create failed: %d\n", ret);
358*25da2beaSAndroid Build Coastguard Worker pthread_mutex_unlock(&rd.mutex);
359*25da2beaSAndroid Build Coastguard Worker return 1;
360*25da2beaSAndroid Build Coastguard Worker }
361*25da2beaSAndroid Build Coastguard Worker
362*25da2beaSAndroid Build Coastguard Worker pthread_mutex_lock(&rd.mutex);
363*25da2beaSAndroid Build Coastguard Worker do_send(socket_direct, alloc);
364*25da2beaSAndroid Build Coastguard Worker pthread_join(recv_thread, &retval);
365*25da2beaSAndroid Build Coastguard Worker return (intptr_t)retval;
366*25da2beaSAndroid Build Coastguard Worker }
367*25da2beaSAndroid Build Coastguard Worker
main(int argc,char * argv[])368*25da2beaSAndroid Build Coastguard Worker int main(int argc, char *argv[])
369*25da2beaSAndroid Build Coastguard Worker {
370*25da2beaSAndroid Build Coastguard Worker int ret;
371*25da2beaSAndroid Build Coastguard Worker
372*25da2beaSAndroid Build Coastguard Worker if (argc > 1)
373*25da2beaSAndroid Build Coastguard Worker return 0;
374*25da2beaSAndroid Build Coastguard Worker
375*25da2beaSAndroid Build Coastguard Worker ret = test(0, 0, 0, 0);
376*25da2beaSAndroid Build Coastguard Worker if (ret) {
377*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "test sqthread=0 failed\n");
378*25da2beaSAndroid Build Coastguard Worker return ret;
379*25da2beaSAndroid Build Coastguard Worker }
380*25da2beaSAndroid Build Coastguard Worker if (no_socket)
381*25da2beaSAndroid Build Coastguard Worker return 0;
382*25da2beaSAndroid Build Coastguard Worker
383*25da2beaSAndroid Build Coastguard Worker ret = test(1, 1, 0, 0);
384*25da2beaSAndroid Build Coastguard Worker if (ret) {
385*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "test sqthread=1 reg=1 failed\n");
386*25da2beaSAndroid Build Coastguard Worker return ret;
387*25da2beaSAndroid Build Coastguard Worker }
388*25da2beaSAndroid Build Coastguard Worker
389*25da2beaSAndroid Build Coastguard Worker ret = test(1, 0, 0, 0);
390*25da2beaSAndroid Build Coastguard Worker if (ret) {
391*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "test sqthread=1 reg=0 failed\n");
392*25da2beaSAndroid Build Coastguard Worker return ret;
393*25da2beaSAndroid Build Coastguard Worker }
394*25da2beaSAndroid Build Coastguard Worker
395*25da2beaSAndroid Build Coastguard Worker ret = test(0, 0, 1, 0);
396*25da2beaSAndroid Build Coastguard Worker if (ret) {
397*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "test sqthread=0 direct=1 failed\n");
398*25da2beaSAndroid Build Coastguard Worker return ret;
399*25da2beaSAndroid Build Coastguard Worker }
400*25da2beaSAndroid Build Coastguard Worker
401*25da2beaSAndroid Build Coastguard Worker ret = test(0, 0, 1, 1);
402*25da2beaSAndroid Build Coastguard Worker if (ret) {
403*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "test sqthread=0 direct=alloc failed\n");
404*25da2beaSAndroid Build Coastguard Worker return ret;
405*25da2beaSAndroid Build Coastguard Worker }
406*25da2beaSAndroid Build Coastguard Worker
407*25da2beaSAndroid Build Coastguard Worker return 0;
408*25da2beaSAndroid Build Coastguard Worker }
409