From 48a0ea2e307a3c9abfa27e29e995a8569a56aa89 Mon Sep 17 00:00:00 2001 From: YuQing <384681@qq.com> Date: Wed, 24 Sep 2025 15:54:03 +0800 Subject: [PATCH] ioevent_set support io_uring --- libfastcommon.spec | 8 +++++++ make.sh | 6 +++--- src/ioevent.c | 1 + src/ioevent.h | 14 ++++++++++++ src/ioevent_loop.c | 54 ++++++++++++++++++++++++++++++++++++---------- src/ioevent_loop.h | 14 +++++++++--- 6 files changed, 80 insertions(+), 17 deletions(-) diff --git a/libfastcommon.spec b/libfastcommon.spec index 98df5f9..605266c 100644 --- a/libfastcommon.spec +++ b/libfastcommon.spec @@ -17,6 +17,14 @@ BuildRequires: libcurl-devel Requires: libcurl Requires: %__cp %__mv %__chmod %__grep %__mkdir %__install %__id +%define kernel_major %(uname -r | cut -d'.' -f1) +%define kernel_minor %(uname -r | cut -d'.' -f2) +%define kernel_ver_int %(expr %{kernel_major} \* 100 + %{kernel_minor}) +%if %{kernel_ver_int} >= 514 +BuildRequires: liburing-devel >= 2.5 +Requires: liburing >= 2.5 +%endif + %description c common functions library extracted from my open source projects FastDFS. this library is very simple and stable. functions including: string, logger, diff --git a/make.sh b/make.sh index 179b656..47e1553 100755 --- a/make.sh +++ b/make.sh @@ -117,10 +117,10 @@ if [ "$uname" = "Linux" ]; then minor_version=$(uname -r | awk -F . '{print $2;}') if [ $major_version -eq 5 ] && [ $minor_version -ge 14 ]; then out=$(grep -F IORING_OP_SEND_ZC /usr/include/liburing/io_uring.h) - if [ -z $out ]; then - IOEVENT_USE=IOEVENT_USE_EPOLL - else + if [ -n "$out" ]; then IOEVENT_USE=IOEVENT_USE_URING + else + IOEVENT_USE=IOEVENT_USE_EPOLL fi elif [ $major_version -gt 5 ]; then IOEVENT_USE=IOEVENT_USE_URING diff --git a/src/ioevent.c b/src/ioevent.c index 8507c1a..aca7e53 100644 --- a/src/ioevent.c +++ b/src/ioevent.c @@ -72,6 +72,7 @@ int ioevent_init(IOEventPoller *ioevent, const int size, return -result; } ioevent->cqe = NULL; + ioevent->submmit_count = 0; #elif IOEVENT_USE_KQUEUE ioevent->poll_fd = kqueue(); if (ioevent->poll_fd < 0) { diff --git a/src/ioevent.h b/src/ioevent.h index e1b4e66..9a0fef8 100644 --- a/src/ioevent.h +++ b/src/ioevent.h @@ -75,6 +75,7 @@ typedef struct ioevent_puller { int extra_events; #if IOEVENT_USE_URING struct io_uring ring; + int submmit_count; #else int poll_fd; struct { @@ -200,6 +201,19 @@ static inline int ioevent_uring_submit(IOEventPoller *ioevent) } } } + +static inline int ioevent_uring_prep_recv(IOEventPoller *ioevent, + int sockfd, void *buf, size_t size, void *user_data) +{ + struct io_uring_sqe *sqe = io_uring_get_sqe(&ioevent->ring); + if (sqe == NULL) { + return ENOSPC; + } + sqe->user_data = (long)user_data; + io_uring_prep_recv(sqe, sockfd, buf, size, 0); + ioevent->submmit_count++; + return 0; +} #endif #ifdef __cplusplus diff --git a/src/ioevent_loop.c b/src/ioevent_loop.c index 200e13a..030f577 100644 --- a/src/ioevent_loop.c +++ b/src/ioevent_loop.c @@ -46,7 +46,11 @@ static int ioevent_process(IOEventPoller *ioevent) count++; pEntry = (IOEventEntry *)ioevent->cqe->user_data; if (pEntry != NULL) { - pEntry->callback(pEntry->fd, ioevent->cqe->res, pEntry); + if (ioevent->cqe->flags & IORING_CQE_F_NOTIF) { + //TODO + } else { + pEntry->callback(pEntry->fd, ioevent->cqe->res, pEntry); + } } } @@ -230,28 +234,56 @@ int ioevent_loop(struct nio_thread_data *thread_data, if (thread_data->thread_loop_callback != NULL) { thread_data->thread_loop_callback(thread_data); } + +#if IOEVENT_USE_URING + if (thread_data->ev_puller.submmit_count > 0) { + thread_data->ev_puller.submmit_count = 0; + if ((result=ioevent_uring_submit(&thread_data->ev_puller)) != 0) { + logError("file: "__FILE__", line: %d, " + "io_uring_submit fail, errno: %d, error info: %s", + __LINE__, result, STRERROR(result)); + return result; + } + } +#endif } return 0; } int ioevent_set(struct fast_task_info *task, struct nio_thread_data *pThread, - int sock, short event, IOEventCallback callback, const int timeout) + int sock, short event, IOEventCallback callback, + const int timeout, const bool use_iouring) { int result; task->thread_data = pThread; task->event.fd = sock; task->event.callback = callback; - if (ioevent_attach(&pThread->ev_puller, sock, event, task) < 0) - { - result = errno != 0 ? errno : ENOENT; - logError("file: "__FILE__", line: %d, " - "ioevent_attach fail, fd: %d, " - "errno: %d, error info: %s", - __LINE__, sock, result, STRERROR(result)); - return result; - } + if (use_iouring) { +#if IOEVENT_USE_URING + if ((result=uring_prep_recv_by_task(task)) != 0) { + logError("file: "__FILE__", line: %d, " + "uring_prep_recv fail, fd: %d, " + "errno: %d, error info: %s", + __LINE__, sock, result, STRERROR(result)); + return result; + } +#else + logError("file: "__FILE__", line: %d, " + "some mistakes happen!", __LINE__); + return EBUSY; +#endif + } else { + if (ioevent_attach(&pThread->ev_puller, sock, event, task) < 0) { + result = errno != 0 ? errno : ENOENT; + logError("file: "__FILE__", line: %d, " + "ioevent_attach fail, fd: %d, " + "errno: %d, error info: %s", + __LINE__, sock, result, STRERROR(result)); + return result; + } + } task->event.timer.expires = g_current_time + timeout; fast_timer_add(&pThread->timer, &task->event.timer); diff --git a/src/ioevent_loop.h b/src/ioevent_loop.h index 44efd4f..aee74fc 100644 --- a/src/ioevent_loop.h +++ b/src/ioevent_loop.h @@ -26,8 +26,9 @@ int ioevent_loop(struct nio_thread_data *thread_data, IOEventCallback recv_notify_callback, TaskCleanUpCallback clean_up_callback, volatile bool *continue_flag); -int ioevent_set(struct fast_task_info *pTask, struct nio_thread_data *pThread, - int sock, short event, IOEventCallback callback, const int timeout); +int ioevent_set(struct fast_task_info *task, struct nio_thread_data *pThread, + int sock, short event, IOEventCallback callback, + const int timeout, const bool use_iouring); static inline bool ioevent_is_canceled(struct fast_task_info *task) { @@ -70,9 +71,16 @@ static inline int ioevent_notify_thread(struct nio_thread_data *thread_data) return 0; } +#if IOEVENT_USE_URING +static inline int uring_prep_recv_by_task(struct fast_task_info *task) +{ + return ioevent_uring_prep_recv(&task->thread_data->ev_puller, + task->event.fd, task->recv.ptr->data, task->recv.ptr->size, task); +} +#endif + #ifdef __cplusplus } #endif #endif -