| 100 | } |
| 101 | |
| 102 | static int receiver(int queue_flags) |
| 103 | { |
| 104 | struct io_uring_sqe *sqe; |
| 105 | struct io_uring_cqe *cqe; |
| 106 | struct io_uring ring; |
| 107 | struct io_uring_napi napi = { }; |
| 108 | struct sockaddr_in addr; |
| 109 | int fd, listen_fd; |
| 110 | int i, ret; |
| 111 | |
| 112 | ret = io_uring_queue_init(8, &ring, queue_flags); |
| 113 | if (ret < 0) { |
| 114 | if (ret == -EINVAL) |
| 115 | return T_EXIT_SKIP; |
| 116 | fprintf(stderr, "queue_init: %s\n", strerror(-ret)); |
| 117 | return 1; |
| 118 | } |
| 119 | |
| 120 | napi.prefer_busy_poll = 1; |
| 121 | napi.busy_poll_to = 50; |
| 122 | io_uring_register_napi(&ring, &napi); |
| 123 | |
| 124 | memset(&addr, 0, sizeof(addr)); |
| 125 | addr.sin_family = AF_INET; |
| 126 | addr.sin_port = htons(port); |
| 127 | addr.sin_addr.s_addr = INADDR_ANY; |
| 128 | |
| 129 | listen_fd = socket(AF_INET, SOCK_STREAM, 0); |
| 130 | assert(listen_fd >= 0); |
| 131 | |
| 132 | do_setsockopt(listen_fd, SOL_SOCKET, SO_REUSEPORT, 1); |
| 133 | ret = bind(listen_fd, (void *)&addr, sizeof(addr)); |
| 134 | if (ret) { |
| 135 | fprintf(stderr, "bind failed %i %i\n", ret, errno); |
| 136 | return 1; |
| 137 | } |
| 138 | |
| 139 | ret = listen(listen_fd, 8); |
| 140 | assert(ret == 0); |
| 141 | |
| 142 | fd = accept(listen_fd, NULL, NULL); |
| 143 | assert(fd >= 0); |
| 144 | |
| 145 | while (1) { |
| 146 | sqe = io_uring_get_sqe(&ring); |
| 147 | io_uring_prep_recv(sqe, fd, buffer, BUF_SIZE, 0); |
| 148 | |
| 149 | ret = io_uring_submit(&ring); |
| 150 | if (ret < 0) { |
| 151 | fprintf(stderr, "io_uring_submit: %i\n", ret); |
| 152 | return 1; |
| 153 | } |
| 154 | |
| 155 | ret = io_uring_wait_cqe(&ring, &cqe); |
| 156 | if (ret < 0) { |
| 157 | fprintf(stderr, "io_uring_wait_cqe: %i\n", ret); |
| 158 | return 1; |
| 159 | } |
no test coverage detected