From 93ac0df93bf453920d2e83f3115cae404418fe14 Mon Sep 17 00:00:00 2001 From: wokron Date: Fri, 9 Jan 2026 16:01:12 +0800 Subject: [PATCH 1/3] add async_uring_cmd and async_cmd_getsockname --- include/condy/async_operations.hpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/include/condy/async_operations.hpp b/include/condy/async_operations.hpp index c78c1d48..6d3825f4 100644 --- a/include/condy/async_operations.hpp +++ b/include/condy/async_operations.hpp @@ -833,6 +833,22 @@ inline auto async_socket_direct(int domain, int type, int protocol, file_index, flags); } +#if !IO_URING_CHECK_VERSION(2, 13) // >= 2.13 +/** + * @brief See io_uring_prep_uring_cmd + */ +template +inline auto async_uring_cmd(int cmd_op, Fd fd, CmdFunc &&cmd_func) { + auto prep_func = [cmd_func = std::forward(cmd_func)]( + io_uring_sqe *sqe, int cmd_op_inner, int fd_inner) { + io_uring_prep_uring_cmd(sqe, cmd_op_inner, fd_inner); + cmd_func(sqe); + }; + auto op = make_op_awaiter(std::move(prep_func), cmd_op, fd); + return detail::maybe_flag_fixed_fd(std::move(op), fd); +} +#endif + #if !IO_URING_CHECK_VERSION(2, 5) // >= 2.5 /** * @brief See io_uring_prep_cmd_sock @@ -846,6 +862,19 @@ inline auto async_cmd_sock(int cmd_op, Fd fd, int level, int optname, } #endif +#if !IO_URING_CHECK_VERSION(2, 13) // >= 2.13 +/** + * @brief See io_uring_prep_cmd_getsockname + */ +template +inline auto async_cmd_getsockname(Fd fd, struct sockaddr *sockaddr, + socklen_t *sockaddr_len, int peer) { + auto op = make_op_awaiter(io_uring_prep_cmd_getsockname, fd, sockaddr, + sockaddr_len, peer); + return detail::maybe_flag_fixed_fd(std::move(op), fd); +} +#endif + #if !IO_URING_CHECK_VERSION(2, 6) // >= 2.6 /** * @brief See io_uring_prep_waitid From 07fc28a6127728a1eb2c9757448419f513ff9ed1 Mon Sep 17 00:00:00 2001 From: wokron Date: Fri, 9 Jan 2026 17:51:53 +0800 Subject: [PATCH 2/3] add tests for async_uring_cmd and async_cmd_getsockname --- tests/test_async_operations.4.cpp | 109 +++++++++++++++++++++++++++++- 1 file changed, 107 insertions(+), 2 deletions(-) diff --git a/tests/test_async_operations.4.cpp b/tests/test_async_operations.4.cpp index 9e09a7b7..5dc2ab5f 100644 --- a/tests/test_async_operations.4.cpp +++ b/tests/test_async_operations.4.cpp @@ -267,13 +267,75 @@ TEST_CASE("test async_operations - test socket - direct") { condy::sync_wait(func()); } +#if !IO_URING_CHECK_VERSION(2, 13) // >= 2.13 +TEST_CASE("test async_operations - test uring_cmd - basic") { + auto my_async_cmd_sock = [](int cmd_op, int fd, int level, int optname, + void *optval, int optlen) { + return condy::async_uring_cmd(cmd_op, fd, [=](io_uring_sqe *sqe) { + sqe->optval = (unsigned long)(uintptr_t)optval; + sqe->optname = optname; + sqe->optlen = optlen; + sqe->level = level; + }); + }; + + int listen_fd = socket(AF_INET, SOCK_STREAM, 0); + REQUIRE(listen_fd >= 0); + + auto func = [&]() -> condy::Coro { + int val = 1; + int r = co_await my_async_cmd_sock(SOCKET_URING_OP_SETSOCKOPT, + listen_fd, SOL_SOCKET, SO_REUSEADDR, + &val, sizeof(val)); + REQUIRE(r == 0); + }; + condy::sync_wait(func()); + + close(listen_fd); +} +#endif + +#if !IO_URING_CHECK_VERSION(2, 13) // >= 2.13 +TEST_CASE("test async_operations - test uring_cmd - fixed fd") { + auto my_async_cmd_sock_fixed = [](int cmd_op, int fd, int level, + int optname, void *optval, int optlen) { + return condy::async_uring_cmd( + cmd_op, condy::fixed(fd), [=](io_uring_sqe *sqe) { + sqe->optval = (unsigned long)(uintptr_t)optval; + sqe->optname = optname; + sqe->optlen = optlen; + sqe->level = level; + }); + }; + + int listen_fd = create_accept_socket(); + + auto func = [&]() -> condy::Coro { + auto &fd_table = condy::current_runtime().fd_table(); + fd_table.init(1); + int r = co_await condy::async_files_update(&listen_fd, 1, 0); + REQUIRE(r == 1); + + int val = 1; + r = co_await my_async_cmd_sock_fixed(SOCKET_URING_OP_SETSOCKOPT, 0, + SOL_SOCKET, SO_REUSEADDR, &val, + sizeof(val)); + REQUIRE(r == 0); + }; + + condy::sync_wait(func()); + + close(listen_fd); +} +#endif + #if !IO_URING_CHECK_VERSION(2, 5) // >= 2.5 TEST_CASE("test async_operations - test cmd_sock - basic") { int listen_fd = socket(AF_INET, SOCK_STREAM, 0); REQUIRE(listen_fd >= 0); auto func = [&]() -> condy::Coro { - int val; + int val = 1; int r = co_await condy::async_cmd_sock(SOCKET_URING_OP_SETSOCKOPT, listen_fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); @@ -295,7 +357,7 @@ TEST_CASE("test async_operations - test cmd_sock - fixed fd") { int r = co_await condy::async_files_update(&listen_fd, 1, 0); REQUIRE(r == 1); - int val; + int val = 1; r = co_await condy::async_cmd_sock(SOCKET_URING_OP_SETSOCKOPT, condy::fixed(0), SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); @@ -306,6 +368,49 @@ TEST_CASE("test async_operations - test cmd_sock - fixed fd") { } #endif +#if !IO_URING_CHECK_VERSION(2, 13) // >= 2.13 +TEST_CASE("test async_operations - test cmd_getsockname - basic") { + int listen_fd = create_accept_socket(); + + auto func = [&]() -> condy::Coro { + struct sockaddr_in addr {}; + socklen_t addrlen = sizeof(addr); + int r = co_await condy::async_cmd_getsockname( + listen_fd, (struct sockaddr *)&addr, &addrlen, 0); + REQUIRE(r == 0); + REQUIRE(addrlen == sizeof(addr)); + REQUIRE(addr.sin_family == AF_INET); + }; + condy::sync_wait(func()); + + close(listen_fd); +} +#endif + +#if !IO_URING_CHECK_VERSION(2, 13) // >= 2.13 +TEST_CASE("test async_operations - test cmd_getsockname - fixed fd") { + int listen_fd = create_accept_socket(); + + auto func = [&]() -> condy::Coro { + auto &fd_table = condy::current_runtime().fd_table(); + fd_table.init(1); + int r = co_await condy::async_files_update(&listen_fd, 1, 0); + REQUIRE(r == 1); + + struct sockaddr_in addr {}; + socklen_t addrlen = sizeof(addr); + r = co_await condy::async_cmd_getsockname( + condy::fixed(0), (struct sockaddr *)&addr, &addrlen, 0); + REQUIRE(r == 0); + REQUIRE(addrlen == sizeof(addr)); + REQUIRE(addr.sin_family == AF_INET); + }; + condy::sync_wait(func()); + + close(listen_fd); +} +#endif + #if !IO_URING_CHECK_VERSION(2, 6) // >= 2.6 TEST_CASE("test async_operations - test waitid") { pid_t pid = fork(); From 425769a99486368c40144a8d13365d3d9f58882e Mon Sep 17 00:00:00 2001 From: wokron Date: Tue, 10 Feb 2026 17:25:51 +0800 Subject: [PATCH 3/3] simplify async_uring_cmd --- include/condy/async_operations.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/condy/async_operations.hpp b/include/condy/async_operations.hpp index 6d3825f4..c453a8d5 100644 --- a/include/condy/async_operations.hpp +++ b/include/condy/async_operations.hpp @@ -839,12 +839,12 @@ inline auto async_socket_direct(int domain, int type, int protocol, */ template inline auto async_uring_cmd(int cmd_op, Fd fd, CmdFunc &&cmd_func) { - auto prep_func = [cmd_func = std::forward(cmd_func)]( - io_uring_sqe *sqe, int cmd_op_inner, int fd_inner) { - io_uring_prep_uring_cmd(sqe, cmd_op_inner, fd_inner); + auto prep_func = [cmd_op, fd, cmd_func = std::forward(cmd_func)]( + io_uring_sqe *sqe) { + io_uring_prep_uring_cmd(sqe, cmd_op, fd); cmd_func(sqe); }; - auto op = make_op_awaiter(std::move(prep_func), cmd_op, fd); + auto op = make_op_awaiter(std::move(prep_func)); return detail::maybe_flag_fixed_fd(std::move(op), fd); } #endif