• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: MIT */
2 /*
3  * Description: test that thread pool issued requests don't cancel on thread
4  *		exit, but do get canceled once the parent exits. Do both
5  *		writes that finish and a poll request that sticks around.
6  *
7  */
8 #include <errno.h>
9 #include <stdio.h>
10 #include <unistd.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <fcntl.h>
14 #include <sys/poll.h>
15 #include <pthread.h>
16 
17 #include "helpers.h"
18 #include "liburing.h"
19 
20 #define NR_IOS	8
21 #define WSIZE	512
22 
23 struct d {
24 	int fd;
25 	struct io_uring *ring;
26 	unsigned long off;
27 	int pipe_fd;
28 	int err;
29 };
30 
do_io(void * data)31 static void *do_io(void *data)
32 {
33 	struct d *d = data;
34 	struct io_uring_sqe *sqe;
35 	char *buffer;
36 	int ret;
37 
38 	buffer = t_malloc(WSIZE);
39 	memset(buffer, 0x5a, WSIZE);
40 	sqe = io_uring_get_sqe(d->ring);
41 	if (!sqe) {
42 		d->err++;
43 		return NULL;
44 	}
45 	io_uring_prep_write(sqe, d->fd, buffer, WSIZE, d->off);
46 	sqe->user_data = d->off;
47 
48 	sqe = io_uring_get_sqe(d->ring);
49 	if (!sqe) {
50 		d->err++;
51 		return NULL;
52 	}
53 	io_uring_prep_poll_add(sqe, d->pipe_fd, POLLIN);
54 
55 	ret = io_uring_submit(d->ring);
56 	if (ret != 2)
57 		d->err++;
58 
59 	free(buffer);
60 	return NULL;
61 }
62 
main(int argc,char * argv[])63 int main(int argc, char *argv[])
64 {
65 	struct io_uring ring;
66 	const char *fname;
67 	pthread_t thread;
68 	int ret, do_unlink, i, fd;
69 	struct d d;
70 	int fds[2];
71 
72 	if (pipe(fds) < 0) {
73 		perror("pipe");
74 		return 1;
75 	}
76 
77 	ret = io_uring_queue_init(32, &ring, 0);
78 	if (ret) {
79 		fprintf(stderr, "ring setup failed\n");
80 		return 1;
81 	}
82 
83 	if (argc > 1) {
84 		fname = argv[1];
85 		do_unlink = 0;
86 	} else {
87 		fname = ".thread.exit";
88 		do_unlink = 1;
89 	}
90 
91 	if (do_unlink)
92 		t_create_file(fname, 4096);
93 
94 	fd = open(fname, O_WRONLY);
95 	if (fd < 0) {
96 		perror("open");
97 		return 1;
98 	}
99 
100 	d.fd = fd;
101 	d.ring = &ring;
102 	d.off = 0;
103 	d.pipe_fd = fds[0];
104 	d.err = 0;
105 	for (i = 0; i < NR_IOS; i++) {
106 		memset(&thread, 0, sizeof(thread));
107 		pthread_create(&thread, NULL, do_io, &d);
108 		pthread_join(thread, NULL);
109 		d.off += WSIZE;
110 	}
111 
112 	for (i = 0; i < NR_IOS; i++) {
113 		struct io_uring_cqe *cqe;
114 
115 		ret = io_uring_wait_cqe(&ring, &cqe);
116 		if (ret) {
117 			fprintf(stderr, "io_uring_wait_cqe=%d\n", ret);
118 			goto err;
119 		}
120 		if (cqe->res != WSIZE) {
121 			fprintf(stderr, "cqe->res=%d, Expected %d\n", cqe->res,
122 								WSIZE);
123 			goto err;
124 		}
125 		io_uring_cqe_seen(&ring, cqe);
126 	}
127 
128 	if (do_unlink)
129 		unlink(fname);
130 	return d.err;
131 err:
132 	if (do_unlink)
133 		unlink(fname);
134 	return 1;
135 }
136