#include "uring.h" #include #include #include "log.h" #include "loglib.h" #include "socket.h" #include "poller.h" static ssize_t __socket_sendmsg(socket_t *s, struct msghdr *m, const endpoint_t *e, struct sockaddr_storage *ss, struct uring_req *r) { ssize_t ret = socket_sendmsg(s, m, e); r->handler(r, 0, 0); return ret; } __thread __typeof(__socket_sendmsg) (*uring_sendmsg) = __socket_sendmsg; #ifdef HAVE_LIBURING #include static __thread struct io_uring rtpe_uring; static ssize_t __uring_sendmsg(socket_t *s, struct msghdr *m, const endpoint_t *e, struct sockaddr_storage *ss, struct uring_req *r) { struct io_uring_sqe *sqe = io_uring_get_sqe(&rtpe_uring); assert(sqe != NULL); s->family->endpoint2sockaddr(ss, e); m->msg_name = ss; m->msg_namelen = s->family->sockaddr_size; io_uring_sqe_set_data(sqe, r); io_uring_prep_sendmsg(sqe, s->fd, m, 0); return 0; } static unsigned int __uring_thread_loop(void) { io_uring_submit_and_get_events(&rtpe_uring); struct io_uring_cqe *cqe; unsigned int head, num = 0; io_uring_for_each_cqe(&rtpe_uring, head, cqe) { struct uring_req *req = io_uring_cqe_get_data(cqe); req->handler(req, cqe->res, cqe->flags); num++; } io_uring_cq_advance(&rtpe_uring, num); return num; } void uring_thread_init(void) { struct io_uring_params params = {0}; int ret = io_uring_queue_init_params(4096, &rtpe_uring, ¶ms); if (ret) die("io_uring init failed (%s)", strerror(errno)); uring_sendmsg = __uring_sendmsg; uring_thread_loop = __uring_thread_loop; } void uring_thread_cleanup(void) { io_uring_queue_exit(&rtpe_uring); } #endif