diff --git a/include/condy/async_operations.hpp b/include/condy/async_operations.hpp index 58341cf6..c05d48b8 100644 --- a/include/condy/async_operations.hpp +++ b/include/condy/async_operations.hpp @@ -930,11 +930,10 @@ inline auto async_uring_cmd128(int cmd_op, Fd fd, CmdFunc &&cmd_func, cmd_func = std::forward(cmd_func)](detail::Ring *ring) { auto *sqe = ring->get_sqe128(); - if (!sqe) { - detail::panic_on("SQE128 not enabled in the ring"); + if (sqe) { + io_uring_prep_uring_cmd128(sqe, cmd_op, fd); + cmd_func(sqe); } - io_uring_prep_uring_cmd128(sqe, cmd_op, fd); - cmd_func(sqe); return sqe; }; auto op = build_op_awaiter(std::move(prep_func), diff --git a/include/condy/detail/async_operations.hpp b/include/condy/detail/async_operations.hpp index 4151939b..578c1acd 100644 --- a/include/condy/detail/async_operations.hpp +++ b/include/condy/detail/async_operations.hpp @@ -42,10 +42,9 @@ auto make_op_awaiter128(Func &&func, Args &&...args) { ... args = unwrap_fixed(std::forward(args))](Ring *ring) { auto *sqe = ring->get_sqe128(); - if (!sqe) { - panic_on("SQE128 not enabled in the ring"); + if (sqe) { + func(sqe, args...); } - func(sqe, args...); return sqe; }; return build_op_awaiter(std::move(prep_func)); diff --git a/include/condy/detail/op_states.hpp b/include/condy/detail/op_states.hpp index b026e51e..f3a68252 100644 --- a/include/condy/detail/op_states.hpp +++ b/include/condy/detail/op_states.hpp @@ -33,9 +33,14 @@ template class OpSenderOperationState { void start(unsigned int flags) noexcept { auto &context = Context::current(); auto &ring = context.runtime()->ring_internal(); - context.runtime()->pend_work_internal(); io_uring_sqe *sqe = prep_func_(&ring); - assert(sqe && "prep_func must return a valid sqe"); + if (sqe == nullptr) { + io_uring_cqe cqe = {}; + cqe.res = -EINVAL; + finish_handle_.get().handle(&cqe); + return; + } + context.runtime()->pend_work_internal(); io_uring_sqe_set_flags(sqe, sqe->flags | flags); auto work = encode_work(&finish_handle_.get(), WorkType::Common); io_uring_sqe_set_data64(sqe, work); diff --git a/tests/test_async_operations.2.cpp b/tests/test_async_operations.2.cpp index 17d77e78..57435ee7 100644 --- a/tests/test_async_operations.2.cpp +++ b/tests/test_async_operations.2.cpp @@ -152,6 +152,17 @@ TEST_CASE("test async_operations - test nop128 - sqe mixed") { } #endif +#if CONDY_URING_VERSION_GE(2, 13) // >= 2.13 +TEST_CASE("test async_operations - test nop128 - no sqe128") { + condy::Runtime runtime; + auto func = [&]() -> condy::Coro { + int r = co_await condy::async_nop128(); + REQUIRE(r == -EINVAL); + }; + condy::sync_wait(runtime, func()); +} +#endif + TEST_CASE("test async_operations - test timeout - basic") { auto func = [&]() -> condy::Coro { __kernel_timespec ts = { diff --git a/tests/test_async_operations.4.cpp b/tests/test_async_operations.4.cpp index 062b016e..dc1c1f42 100644 --- a/tests/test_async_operations.4.cpp +++ b/tests/test_async_operations.4.cpp @@ -493,6 +493,26 @@ TEST_CASE("test async_operations - test uring_cmd_multishot - tx timestamp") { } #endif +#if CONDY_URING_VERSION_GE(2, 13) // >= 2.13 +TEST_CASE("test async_operations - test uring_cmd128 - no sqe128") { + condy::Runtime runtime; + + 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 == -EINVAL); + }; + condy::sync_wait(runtime, func()); + + close(listen_fd); +} +#endif + #if CONDY_URING_VERSION_GE(2, 13) // >= 2.13 TEST_CASE("test async_operations - test uring_cmd128 - cmd sock - basic") { condy::Runtime runtime(