From 0381f8096a32522c394356b2364f8f1deec01c16 Mon Sep 17 00:00:00 2001 From: wokron Date: Thu, 12 Feb 2026 17:22:32 +0800 Subject: [PATCH 1/5] add build_op_awaiter api --- include/condy/awaiter_operations.hpp | 53 +++++++++++++++++++--------- 1 file changed, 37 insertions(+), 16 deletions(-) diff --git a/include/condy/awaiter_operations.hpp b/include/condy/awaiter_operations.hpp index bba1660f..a830e8b9 100644 --- a/include/condy/awaiter_operations.hpp +++ b/include/condy/awaiter_operations.hpp @@ -16,6 +16,33 @@ namespace condy { +template +auto build_op_awaiter(PrepFunc &&func, Args &&...handler_args) { + return OpAwaiter, CQEHandler>( + std::forward(func), std::forward(handler_args)...); +} + +template +auto build_multishot_op_awaiter(PrepFunc &&func, MultiShotFunc &&multishot_func, + Args &&...handler_args) { + return MultiShotOpAwaiter, CQEHandler, + std::decay_t>( + std::forward(func), + std::forward(multishot_func), + std::forward(handler_args)...); +} + +template +auto build_zero_copy_op_awaiter(PrepFunc &&func, FreeFunc &&free_func, + Args &&...handler_args) { + return ZeroCopyOpAwaiter, CQEHandler, + std::decay_t>( + std::forward(func), std::forward(free_func), + std::forward(handler_args)...); +} + /** * @brief This function creates a variant of OpAwaiter. OpAwaiter represents an * asynchronous operation that can be awaited. It is basically a wrapper around @@ -29,8 +56,7 @@ auto make_op_awaiter(Func &&func, Args &&...args) { func(sqe, args...); return sqe; }; - return OpAwaiter( - std::move(prep_func)); + return build_op_awaiter(std::move(prep_func)); } #if !IO_URING_CHECK_VERSION(2, 13) // >= 2.13 @@ -45,8 +71,7 @@ auto make_op_awaiter128(Func &&func, Args &&...args) { func(sqe, args...); return sqe; }; - return OpAwaiter( - std::move(prep_func)); + return build_op_awaiter(std::move(prep_func)); } #endif @@ -62,8 +87,7 @@ auto make_multishot_op_awaiter(MultiShotFunc &&multishot_func, Func &&func, func(sqe, args...); return sqe; }; - return MultiShotOpAwaiter>( + return build_multishot_op_awaiter( std::move(prep_func), std::forward(multishot_func)); } @@ -80,8 +104,8 @@ auto make_select_buffer_op_awaiter(Br *buffers, Func &&func, Args &&...args) { sqe->buf_group = bgid; return sqe; }; - return OpAwaiter>( - std::move(prep_func), buffers); + return build_op_awaiter>(std::move(prep_func), + buffers); } /** @@ -100,8 +124,7 @@ auto make_multishot_select_buffer_op_awaiter(MultiShotFunc &&multishot_func, sqe->buf_group = bgid; return sqe; }; - return MultiShotOpAwaiter, - std::decay_t>( + return build_multishot_op_awaiter>( std::move(prep_func), std::forward(multishot_func), buffers); } @@ -122,8 +145,8 @@ auto make_bundle_select_buffer_op_awaiter(Br *buffers, Func &&func, sqe->ioprio |= IORING_RECVSEND_BUNDLE; return sqe; }; - return OpAwaiter>( - std::move(prep_func), buffers); + return build_op_awaiter>(std::move(prep_func), + buffers); } #endif @@ -144,8 +167,7 @@ auto make_multishot_bundle_select_buffer_op_awaiter( sqe->ioprio |= IORING_RECVSEND_BUNDLE; return sqe; }; - return MultiShotOpAwaiter, - std::decay_t>( + return build_multishot_op_awaiter>( std::move(prep_func), std::forward(multishot_func), buffers); } @@ -163,8 +185,7 @@ auto make_zero_copy_op_awaiter(FreeFunc &&free_func, Func &&func, func(sqe, args...); return sqe; }; - return ZeroCopyOpAwaiter>( + return build_zero_copy_op_awaiter( std::move(prep_func), std::forward(free_func)); } From 5db06bce11bdbe289e08bd54b7492cdca666c83b Mon Sep 17 00:00:00 2001 From: wokron Date: Thu, 12 Feb 2026 17:54:48 +0800 Subject: [PATCH 2/5] move make_op_awaiter to detail ns --- include/condy/awaiter_operations.hpp | 30 ++++------------------------ 1 file changed, 4 insertions(+), 26 deletions(-) diff --git a/include/condy/awaiter_operations.hpp b/include/condy/awaiter_operations.hpp index a830e8b9..7dcabd4a 100644 --- a/include/condy/awaiter_operations.hpp +++ b/include/condy/awaiter_operations.hpp @@ -43,11 +43,8 @@ auto build_zero_copy_op_awaiter(PrepFunc &&func, FreeFunc &&free_func, std::forward(handler_args)...); } -/** - * @brief This function creates a variant of OpAwaiter. OpAwaiter represents an - * asynchronous operation that can be awaited. It is basically a wrapper around - * an io_uring sqe preparation function. - */ +namespace detail { + template auto make_op_awaiter(Func &&func, Args &&...args) { auto prep_func = [func = std::forward(func), @@ -60,9 +57,6 @@ auto make_op_awaiter(Func &&func, Args &&...args) { } #if !IO_URING_CHECK_VERSION(2, 13) // >= 2.13 -/** - * @copydoc make_op_awaiter - */ template auto make_op_awaiter128(Func &&func, Args &&...args) { auto prep_func = [func = std::forward(func), @@ -75,9 +69,6 @@ auto make_op_awaiter128(Func &&func, Args &&...args) { } #endif -/** - * @copydoc make_op_awaiter - */ template auto make_multishot_op_awaiter(MultiShotFunc &&multishot_func, Func &&func, Args &&...args) { @@ -91,9 +82,6 @@ auto make_multishot_op_awaiter(MultiShotFunc &&multishot_func, Func &&func, std::move(prep_func), std::forward(multishot_func)); } -/** - * @copydoc make_op_awaiter - */ template auto make_select_buffer_op_awaiter(Br *buffers, Func &&func, Args &&...args) { auto prep_func = [bgid = buffers->bgid(), func = std::forward(func), @@ -108,9 +96,6 @@ auto make_select_buffer_op_awaiter(Br *buffers, Func &&func, Args &&...args) { buffers); } -/** - * @copydoc make_op_awaiter - */ template auto make_multishot_select_buffer_op_awaiter(MultiShotFunc &&multishot_func, @@ -130,9 +115,6 @@ auto make_multishot_select_buffer_op_awaiter(MultiShotFunc &&multishot_func, } #if !IO_URING_CHECK_VERSION(2, 7) // >= 2.7 -/** - * @copydoc make_op_awaiter - */ template auto make_bundle_select_buffer_op_awaiter(Br *buffers, Func &&func, Args &&...args) { @@ -151,9 +133,6 @@ auto make_bundle_select_buffer_op_awaiter(Br *buffers, Func &&func, #endif #if !IO_URING_CHECK_VERSION(2, 7) // >= 2.7 -/** - * @copydoc make_op_awaiter - */ template auto make_multishot_bundle_select_buffer_op_awaiter( @@ -173,9 +152,6 @@ auto make_multishot_bundle_select_buffer_op_awaiter( } #endif -/** - * @copydoc make_op_awaiter - */ template auto make_zero_copy_op_awaiter(FreeFunc &&free_func, Func &&func, Args &&...args) { @@ -189,6 +165,8 @@ auto make_zero_copy_op_awaiter(FreeFunc &&free_func, Func &&func, std::move(prep_func), std::forward(free_func)); } +} // namespace detail + /** * @brief Decorates an awaiter with specific io_uring sqe flags. * @tparam Flags The io_uring sqe flags to set. From 5ae73a649d414866f78ad97e031f96347a22f27e Mon Sep 17 00:00:00 2001 From: wokron Date: Thu, 12 Feb 2026 17:57:57 +0800 Subject: [PATCH 3/5] fix usage --- include/condy/async_operations.hpp | 280 +++++++++++++++-------------- tests/test_awaiter_operations.cpp | 89 +++++---- tests/test_buffer_table.cpp | 8 +- tests/test_fd_table.cpp | 8 +- tests/test_op_awaiter.cpp | 21 +-- tests/test_runtime.cpp | 10 +- tests/test_task.cpp | 13 +- 7 files changed, 231 insertions(+), 198 deletions(-) diff --git a/include/condy/async_operations.hpp b/include/condy/async_operations.hpp index 96280516..22f40277 100644 --- a/include/condy/async_operations.hpp +++ b/include/condy/async_operations.hpp @@ -41,8 +41,8 @@ inline auto async_splice(Fd1 fd_in, int64_t off_in, Fd2 fd_out, int64_t off_out, if constexpr (detail::is_fixed_fd_v) { splice_flags |= SPLICE_F_FD_IN_FIXED; } - auto op = make_op_awaiter(io_uring_prep_splice, fd_in, off_in, fd_out, - off_out, nbytes, splice_flags); + auto op = detail::make_op_awaiter(io_uring_prep_splice, fd_in, off_in, + fd_out, off_out, nbytes, splice_flags); return detail::maybe_flag_fixed_fd(std::move(op), fd_out); } @@ -55,8 +55,8 @@ inline auto async_tee(Fd1 fd_in, Fd2 fd_out, unsigned int nbytes, if constexpr (detail::is_fixed_fd_v) { splice_flags |= SPLICE_F_FD_IN_FIXED; } - auto op = - make_op_awaiter(io_uring_prep_tee, fd_in, fd_out, nbytes, splice_flags); + auto op = detail::make_op_awaiter(io_uring_prep_tee, fd_in, fd_out, nbytes, + splice_flags); return detail::maybe_flag_fixed_fd(std::move(op), fd_out); } @@ -66,8 +66,8 @@ inline auto async_tee(Fd1 fd_in, Fd2 fd_out, unsigned int nbytes, template inline auto async_readv(Fd fd, const struct iovec *iovecs, unsigned nr_vecs, __u64 offset, int flags) { - auto op = make_op_awaiter(io_uring_prep_readv2, fd, iovecs, nr_vecs, offset, - flags); + auto op = detail::make_op_awaiter(io_uring_prep_readv2, fd, iovecs, nr_vecs, + offset, flags); return detail::maybe_flag_fixed_fd(std::move(op), fd); } @@ -78,8 +78,9 @@ inline auto async_readv(Fd fd, const struct iovec *iovecs, unsigned nr_vecs, template inline auto async_readv(Fd fd, detail::FixedBuffer iovecs, unsigned nr_vecs, __u64 offset, int flags) { - auto op = make_op_awaiter(io_uring_prep_readv_fixed, fd, iovecs.value, - nr_vecs, offset, flags, iovecs.buf_index); + auto op = + detail::make_op_awaiter(io_uring_prep_readv_fixed, fd, iovecs.value, + nr_vecs, offset, flags, iovecs.buf_index); return detail::maybe_flag_fixed_fd(std::move(op), fd); } #endif @@ -90,8 +91,8 @@ template */ inline auto async_writev(Fd fd, const struct iovec *iovecs, unsigned int nr_vecs, __u64 offset, int flags) { - auto op = make_op_awaiter(io_uring_prep_writev2, fd, iovecs, nr_vecs, - offset, flags); + auto op = detail::make_op_awaiter(io_uring_prep_writev2, fd, iovecs, + nr_vecs, offset, flags); return detail::maybe_flag_fixed_fd(std::move(op), fd); } @@ -102,8 +103,9 @@ inline auto async_writev(Fd fd, const struct iovec *iovecs, template inline auto async_writev(Fd fd, detail::FixedBuffer iovecs, unsigned int nr_vecs, __u64 offset, int flags) { - auto op = make_op_awaiter(io_uring_prep_writev_fixed, fd, iovecs.value, - nr_vecs, offset, flags, iovecs.buf_index); + auto op = + detail::make_op_awaiter(io_uring_prep_writev_fixed, fd, iovecs.value, + nr_vecs, offset, flags, iovecs.buf_index); return detail::maybe_flag_fixed_fd(std::move(op), fd); } #endif @@ -113,7 +115,7 @@ inline auto async_writev(Fd fd, detail::FixedBuffer iovecs, */ template inline auto async_recvmsg(Fd fd, struct msghdr *msg, unsigned flags) { - auto op = make_op_awaiter(io_uring_prep_recvmsg, fd, msg, flags); + auto op = detail::make_op_awaiter(io_uring_prep_recvmsg, fd, msg, flags); return detail::maybe_flag_fixed_fd(std::move(op), fd); } @@ -123,7 +125,7 @@ inline auto async_recvmsg(Fd fd, struct msghdr *msg, unsigned flags) { template inline auto async_recvmsg_multishot(Fd fd, struct msghdr *msg, unsigned flags, Buffer &buf, MultiShotFunc &&func) { - auto op = make_multishot_select_buffer_op_awaiter( + auto op = detail::make_multishot_select_buffer_op_awaiter( std::forward(func), &buf, io_uring_prep_recvmsg_multishot, fd, msg, flags); return detail::maybe_flag_fixed_fd(std::move(op), fd); @@ -134,7 +136,7 @@ inline auto async_recvmsg_multishot(Fd fd, struct msghdr *msg, unsigned flags, */ template inline auto async_sendmsg(Fd fd, const struct msghdr *msg, unsigned flags) { - auto op = make_op_awaiter(io_uring_prep_sendmsg, fd, msg, flags); + auto op = detail::make_op_awaiter(io_uring_prep_sendmsg, fd, msg, flags); return detail::maybe_flag_fixed_fd(std::move(op), fd); } @@ -144,7 +146,7 @@ inline auto async_sendmsg(Fd fd, const struct msghdr *msg, unsigned flags) { template inline auto async_sendmsg_zc(Fd fd, const struct msghdr *msg, unsigned flags, FreeFunc &&func) { - auto op = make_zero_copy_op_awaiter( + auto op = detail::make_zero_copy_op_awaiter( std::forward(func), io_uring_prep_sendmsg_zc, fd, msg, flags); return detail::maybe_flag_fixed_fd(std::move(op), fd); } @@ -156,9 +158,9 @@ inline auto async_sendmsg_zc(Fd fd, const struct msghdr *msg, unsigned flags, template inline auto async_sendmsg_zc(Fd fd, detail::FixedBuffer msg, unsigned flags, FreeFunc &&func) { - auto op = make_zero_copy_op_awaiter(std::forward(func), - io_uring_prep_sendmsg_zc_fixed, fd, - msg.value, flags, msg.buf_index); + auto op = detail::make_zero_copy_op_awaiter( + std::forward(func), io_uring_prep_sendmsg_zc_fixed, fd, + msg.value, flags, msg.buf_index); return detail::maybe_flag_fixed_fd(std::move(op), fd); } #endif @@ -167,20 +169,22 @@ inline auto async_sendmsg_zc(Fd fd, detail::FixedBuffer msg, * @brief See io_uring_prep_fsync */ template inline auto async_fsync(Fd fd, unsigned fsync_flags) { - auto op = make_op_awaiter(io_uring_prep_fsync, fd, fsync_flags); + auto op = detail::make_op_awaiter(io_uring_prep_fsync, fd, fsync_flags); return detail::maybe_flag_fixed_fd(std::move(op), fd); } /** * @brief See io_uring_prep_nop */ -inline auto async_nop() { return make_op_awaiter(io_uring_prep_nop); } +inline auto async_nop() { return detail::make_op_awaiter(io_uring_prep_nop); } #if !IO_URING_CHECK_VERSION(2, 13) // >= 2.13 /** * @brief See io_uring_prep_nop128 */ -inline auto async_nop128() { return make_op_awaiter128(io_uring_prep_nop128); } +inline auto async_nop128() { + return detail::make_op_awaiter128(io_uring_prep_nop128); +} #endif /** @@ -188,7 +192,7 @@ inline auto async_nop128() { return make_op_awaiter128(io_uring_prep_nop128); } */ inline auto async_timeout(struct __kernel_timespec *ts, unsigned count, unsigned flags) { - return make_op_awaiter(io_uring_prep_timeout, ts, count, flags); + return detail::make_op_awaiter(io_uring_prep_timeout, ts, count, flags); } #if !IO_URING_CHECK_VERSION(2, 4) // >= 2.4 @@ -200,9 +204,9 @@ template inline auto async_timeout_multishot(struct __kernel_timespec *ts, unsigned count, unsigned flags, MultiShotFunc &&func) { - return make_multishot_op_awaiter(std::forward(func), - io_uring_prep_timeout, ts, count, - flags | IORING_TIMEOUT_MULTISHOT); + return detail::make_multishot_op_awaiter(std::forward(func), + io_uring_prep_timeout, ts, count, + flags | IORING_TIMEOUT_MULTISHOT); } #endif @@ -212,7 +216,8 @@ inline auto async_timeout_multishot(struct __kernel_timespec *ts, template inline auto async_accept(Fd fd, struct sockaddr *addr, socklen_t *addrlen, int flags) { - auto op = make_op_awaiter(io_uring_prep_accept, fd, addr, addrlen, flags); + auto op = + detail::make_op_awaiter(io_uring_prep_accept, fd, addr, addrlen, flags); return detail::maybe_flag_fixed_fd(std::move(op), fd); } @@ -223,8 +228,8 @@ template inline auto async_accept_direct(Fd fd, struct sockaddr *addr, socklen_t *addrlen, int flags, unsigned int file_index) { - auto op = make_op_awaiter(io_uring_prep_accept_direct, fd, addr, addrlen, - flags, file_index); + auto op = detail::make_op_awaiter(io_uring_prep_accept_direct, fd, addr, + addrlen, flags, file_index); return detail::maybe_flag_fixed_fd(std::move(op), fd); } @@ -235,9 +240,9 @@ template inline auto async_multishot_accept(Fd fd, struct sockaddr *addr, socklen_t *addrlen, int flags, MultiShotFunc &&func) { - auto op = make_multishot_op_awaiter(std::forward(func), - io_uring_prep_multishot_accept, fd, - addr, addrlen, flags); + auto op = detail::make_multishot_op_awaiter( + std::forward(func), io_uring_prep_multishot_accept, fd, + addr, addrlen, flags); return detail::maybe_flag_fixed_fd(std::move(op), fd); } @@ -248,9 +253,9 @@ template inline auto async_multishot_accept_direct(Fd fd, struct sockaddr *addr, socklen_t *addrlen, int flags, MultiShotFunc &&func) { - auto op = make_multishot_op_awaiter(std::forward(func), - io_uring_prep_multishot_accept_direct, - fd, addr, addrlen, flags); + auto op = detail::make_multishot_op_awaiter( + std::forward(func), + io_uring_prep_multishot_accept_direct, fd, addr, addrlen, flags); return detail::maybe_flag_fixed_fd(std::move(op), fd); } @@ -261,14 +266,14 @@ template inline auto async_cancel_fd(Fd fd, unsigned int flags) { if constexpr (detail::is_fixed_fd_v) { flags |= IORING_ASYNC_CANCEL_FD_FIXED; } - return make_op_awaiter(io_uring_prep_cancel_fd, fd, flags); + return detail::make_op_awaiter(io_uring_prep_cancel_fd, fd, flags); } /** * @brief See io_uring_prep_link_timeout */ inline auto async_link_timeout(struct __kernel_timespec *ts, unsigned flags) { - return make_op_awaiter(io_uring_prep_link_timeout, ts, flags); + return detail::make_op_awaiter(io_uring_prep_link_timeout, ts, flags); } /** @@ -277,7 +282,7 @@ inline auto async_link_timeout(struct __kernel_timespec *ts, unsigned flags) { template inline auto async_connect(Fd fd, const struct sockaddr *addr, socklen_t addrlen) { - auto op = make_op_awaiter(io_uring_prep_connect, fd, addr, addrlen); + auto op = detail::make_op_awaiter(io_uring_prep_connect, fd, addr, addrlen); return detail::maybe_flag_fixed_fd(std::move(op), fd); } @@ -285,7 +290,8 @@ inline auto async_connect(Fd fd, const struct sockaddr *addr, * @brief See io_uring_prep_files_update */ inline auto async_files_update(int *fds, unsigned nr_fds, int offset) { - return make_op_awaiter(io_uring_prep_files_update, fds, nr_fds, offset); + return detail::make_op_awaiter(io_uring_prep_files_update, fds, nr_fds, + offset); } /** @@ -293,7 +299,8 @@ inline auto async_files_update(int *fds, unsigned nr_fds, int offset) { */ template inline auto async_fallocate(Fd fd, int mode, __u64 offset, __u64 len) { - auto op = make_op_awaiter(io_uring_prep_fallocate, fd, mode, offset, len); + auto op = + detail::make_op_awaiter(io_uring_prep_fallocate, fd, mode, offset, len); return detail::maybe_flag_fixed_fd(std::move(op), fd); } @@ -301,7 +308,8 @@ inline auto async_fallocate(Fd fd, int mode, __u64 offset, __u64 len) { * @brief See io_uring_prep_openat */ inline auto async_openat(int dfd, const char *path, int flags, mode_t mode) { - return make_op_awaiter(io_uring_prep_openat, dfd, path, flags, mode); + return detail::make_op_awaiter(io_uring_prep_openat, dfd, path, flags, + mode); } /** @@ -309,8 +317,8 @@ inline auto async_openat(int dfd, const char *path, int flags, mode_t mode) { */ inline auto async_openat_direct(int dfd, const char *path, int flags, mode_t mode, unsigned file_index) { - return make_op_awaiter(io_uring_prep_openat_direct, dfd, path, flags, mode, - file_index); + return detail::make_op_awaiter(io_uring_prep_openat_direct, dfd, path, + flags, mode, file_index); } /** @@ -332,14 +340,14 @@ inline auto async_open_direct(const char *path, int flags, mode_t mode, * @brief See io_uring_prep_close */ inline auto async_close(int fd) { - return make_op_awaiter(io_uring_prep_close, fd); + return detail::make_op_awaiter(io_uring_prep_close, fd); } /** * @brief See io_uring_prep_close_direct */ inline auto async_close(detail::FixedFd fd) { - return make_op_awaiter(io_uring_prep_close_direct, fd); + return detail::make_op_awaiter(io_uring_prep_close_direct, fd); } /** @@ -347,8 +355,8 @@ inline auto async_close(detail::FixedFd fd) { */ template inline auto async_read(Fd fd, Buffer &&buf, __u64 offset) { - auto op = - make_op_awaiter(io_uring_prep_read, fd, buf.data(), buf.size(), offset); + auto op = detail::make_op_awaiter(io_uring_prep_read, fd, buf.data(), + buf.size(), offset); return detail::maybe_flag_fixed_fd(std::move(op), fd); } @@ -357,8 +365,9 @@ inline auto async_read(Fd fd, Buffer &&buf, __u64 offset) { */ template inline auto async_read(Fd fd, detail::FixedBuffer buf, __u64 offset) { - auto op = make_op_awaiter(io_uring_prep_read_fixed, fd, buf.value.data(), - buf.value.size(), offset, buf.buf_index); + auto op = + detail::make_op_awaiter(io_uring_prep_read_fixed, fd, buf.value.data(), + buf.value.size(), offset, buf.buf_index); return detail::maybe_flag_fixed_fd(std::move(op), fd); } @@ -367,8 +376,8 @@ inline auto async_read(Fd fd, detail::FixedBuffer buf, __u64 offset) { */ template inline auto async_read(Fd fd, Buffer &buf, __u64 offset) { - auto op = make_select_buffer_op_awaiter(&buf, io_uring_prep_read, fd, - nullptr, 0, offset); + auto op = detail::make_select_buffer_op_awaiter(&buf, io_uring_prep_read, + fd, nullptr, 0, offset); return detail::maybe_flag_fixed_fd(std::move(op), fd); } @@ -379,7 +388,7 @@ inline auto async_read(Fd fd, Buffer &buf, __u64 offset) { template inline auto async_read_multishot(Fd fd, Buffer &buf, __u64 offset, MultiShotFunc &&func) { - auto op = make_multishot_select_buffer_op_awaiter( + auto op = detail::make_multishot_select_buffer_op_awaiter( std::forward(func), &buf, io_uring_prep_read_multishot, fd, 0, offset, buf.bgid()); return detail::maybe_flag_fixed_fd(std::move(op), fd); @@ -391,8 +400,8 @@ inline auto async_read_multishot(Fd fd, Buffer &buf, __u64 offset, */ template inline auto async_write(Fd fd, Buffer &&buf, __u64 offset) { - auto op = make_op_awaiter(io_uring_prep_write, fd, buf.data(), buf.size(), - offset); + auto op = detail::make_op_awaiter(io_uring_prep_write, fd, buf.data(), + buf.size(), offset); return detail::maybe_flag_fixed_fd(std::move(op), fd); } @@ -401,8 +410,9 @@ inline auto async_write(Fd fd, Buffer &&buf, __u64 offset) { */ template inline auto async_write(Fd fd, detail::FixedBuffer buf, __u64 offset) { - auto op = make_op_awaiter(io_uring_prep_write_fixed, fd, buf.value.data(), - buf.value.size(), offset, buf.buf_index); + auto op = + detail::make_op_awaiter(io_uring_prep_write_fixed, fd, buf.value.data(), + buf.value.size(), offset, buf.buf_index); return detail::maybe_flag_fixed_fd(std::move(op), fd); } @@ -411,8 +421,8 @@ inline auto async_write(Fd fd, detail::FixedBuffer buf, __u64 offset) { */ inline auto async_statx(int dfd, const char *path, int flags, unsigned mask, struct statx *statxbuf) { - return make_op_awaiter(io_uring_prep_statx, dfd, path, flags, mask, - statxbuf); + return detail::make_op_awaiter(io_uring_prep_statx, dfd, path, flags, mask, + statxbuf); } /** @@ -420,7 +430,8 @@ inline auto async_statx(int dfd, const char *path, int flags, unsigned mask, */ template inline auto async_fadvise(Fd fd, __u64 offset, off_t len, int advice) { - auto op = make_op_awaiter(io_uring_prep_fadvise, fd, offset, len, advice); + auto op = + detail::make_op_awaiter(io_uring_prep_fadvise, fd, offset, len, advice); return detail::maybe_flag_fixed_fd(std::move(op), fd); } @@ -430,7 +441,8 @@ inline auto async_fadvise(Fd fd, __u64 offset, off_t len, int advice) { */ template inline auto async_fadvise64(Fd fd, __u64 offset, off_t len, int advice) { - auto op = make_op_awaiter(io_uring_prep_fadvise64, fd, offset, len, advice); + auto op = detail::make_op_awaiter(io_uring_prep_fadvise64, fd, offset, len, + advice); return detail::maybe_flag_fixed_fd(std::move(op), fd); } #endif @@ -439,7 +451,7 @@ inline auto async_fadvise64(Fd fd, __u64 offset, off_t len, int advice) { * @brief See io_uring_prep_madvise */ inline auto async_madvise(void *addr, __u32 length, int advice) { - return make_op_awaiter(io_uring_prep_madvise, addr, length, advice); + return detail::make_op_awaiter(io_uring_prep_madvise, addr, length, advice); } #if !IO_URING_CHECK_VERSION(2, 7) // >= 2.7 @@ -447,7 +459,8 @@ inline auto async_madvise(void *addr, __u32 length, int advice) { * @brief See io_uring_prep_madvise64 */ inline auto async_madvise64(void *addr, off_t length, int advice) { - auto op = make_op_awaiter(io_uring_prep_madvise64, addr, length, advice); + auto op = + detail::make_op_awaiter(io_uring_prep_madvise64, addr, length, advice); return op; } #endif @@ -500,8 +513,8 @@ inline void prep_sendto_zc_fixed(io_uring_sqe *sqe, int sockfd, const void *buf, */ template inline auto async_send(Fd sockfd, Buffer &&buf, int flags) { - auto op = make_op_awaiter(io_uring_prep_send, sockfd, buf.data(), - buf.size(), flags); + auto op = detail::make_op_awaiter(io_uring_prep_send, sockfd, buf.data(), + buf.size(), flags); return detail::maybe_flag_fixed_fd(std::move(op), sockfd); } @@ -510,8 +523,8 @@ inline auto async_send(Fd sockfd, Buffer &&buf, int flags) { */ template inline auto async_send(Fd sockfd, ProvidedBufferQueue &buf, int flags) { - auto op = make_select_buffer_op_awaiter(&buf, io_uring_prep_send, sockfd, - nullptr, 0, flags); + auto op = detail::make_select_buffer_op_awaiter(&buf, io_uring_prep_send, + sockfd, nullptr, 0, flags); return detail::maybe_flag_fixed_fd(std::move(op), sockfd); } @@ -521,8 +534,8 @@ inline auto async_send(Fd sockfd, ProvidedBufferQueue &buf, int flags) { */ template inline auto async_send(Fd sockfd, BundledProvidedBufferQueue &buf, int flags) { - auto op = make_bundle_select_buffer_op_awaiter(&buf, io_uring_prep_send, - sockfd, nullptr, 0, flags); + auto op = detail::make_bundle_select_buffer_op_awaiter( + &buf, io_uring_prep_send, sockfd, nullptr, 0, flags); return detail::maybe_flag_fixed_fd(std::move(op), sockfd); } #endif @@ -533,8 +546,8 @@ inline auto async_send(Fd sockfd, BundledProvidedBufferQueue &buf, int flags) { template inline auto async_sendto(Fd sockfd, Buffer &&buf, int flags, const struct sockaddr *addr, socklen_t addrlen) { - auto op = make_op_awaiter(detail::prep_sendto, sockfd, buf.data(), - buf.size(), flags, addr, addrlen); + auto op = detail::make_op_awaiter(detail::prep_sendto, sockfd, buf.data(), + buf.size(), flags, addr, addrlen); return detail::maybe_flag_fixed_fd(std::move(op), sockfd); } @@ -544,8 +557,8 @@ inline auto async_sendto(Fd sockfd, Buffer &&buf, int flags, template inline auto async_sendto(Fd sockfd, ProvidedBufferQueue &buf, int flags, const struct sockaddr *addr, socklen_t addrlen) { - auto op = make_select_buffer_op_awaiter(&buf, detail::prep_sendto, sockfd, - nullptr, 0, flags, addr, addrlen); + auto op = detail::make_select_buffer_op_awaiter( + &buf, detail::prep_sendto, sockfd, nullptr, 0, flags, addr, addrlen); return detail::maybe_flag_fixed_fd(std::move(op), sockfd); } @@ -556,7 +569,7 @@ inline auto async_sendto(Fd sockfd, ProvidedBufferQueue &buf, int flags, template inline auto async_sendto(Fd sockfd, BundledProvidedBufferQueue &buf, int flags, const struct sockaddr *addr, socklen_t addrlen) { - auto op = make_bundle_select_buffer_op_awaiter( + auto op = detail::make_bundle_select_buffer_op_awaiter( &buf, detail::prep_sendto, sockfd, nullptr, 0, flags, addr, addrlen); return detail::maybe_flag_fixed_fd(std::move(op), sockfd); } @@ -568,7 +581,7 @@ inline auto async_sendto(Fd sockfd, BundledProvidedBufferQueue &buf, int flags, template inline auto async_send_zc(Fd sockfd, Buffer &&buf, int flags, unsigned zc_flags, FreeFunc &&func) { - auto op = make_zero_copy_op_awaiter( + auto op = detail::make_zero_copy_op_awaiter( std::forward(func), io_uring_prep_send_zc, sockfd, buf.data(), buf.size(), flags, zc_flags); return detail::maybe_flag_fixed_fd(std::move(op), sockfd); @@ -580,7 +593,7 @@ inline auto async_send_zc(Fd sockfd, Buffer &&buf, int flags, unsigned zc_flags, template inline auto async_send_zc(Fd sockfd, detail::FixedBuffer buf, int flags, unsigned zc_flags, FreeFunc &&func) { - auto op = make_zero_copy_op_awaiter( + auto op = detail::make_zero_copy_op_awaiter( std::forward(func), io_uring_prep_send_zc_fixed, sockfd, buf.value.data(), buf.value.size(), flags, zc_flags, buf.buf_index); return detail::maybe_flag_fixed_fd(std::move(op), sockfd); @@ -593,7 +606,7 @@ template inline auto async_sendto_zc(Fd sockfd, Buffer &&buf, int flags, const struct sockaddr *addr, socklen_t addrlen, unsigned zc_flags, FreeFunc &&func) { - auto op = make_zero_copy_op_awaiter( + auto op = detail::make_zero_copy_op_awaiter( std::forward(func), detail::prep_sendto_zc, sockfd, buf.data(), buf.size(), flags, addr, addrlen, zc_flags); return detail::maybe_flag_fixed_fd(std::move(op), sockfd); @@ -607,7 +620,7 @@ inline auto async_sendto_zc(Fd sockfd, detail::FixedBuffer buf, int flags, const struct sockaddr *addr, socklen_t addrlen, unsigned zc_flags, FreeFunc &&func) { - auto op = make_zero_copy_op_awaiter( + auto op = detail::make_zero_copy_op_awaiter( std::forward(func), detail::prep_sendto_zc_fixed, sockfd, buf.value.data(), buf.value.size(), flags, addr, addrlen, zc_flags, buf.buf_index); @@ -619,8 +632,8 @@ inline auto async_sendto_zc(Fd sockfd, detail::FixedBuffer buf, */ template inline auto async_recv(Fd sockfd, Buffer &&buf, int flags) { - auto op = make_op_awaiter(io_uring_prep_recv, sockfd, buf.data(), - buf.size(), flags); + auto op = detail::make_op_awaiter(io_uring_prep_recv, sockfd, buf.data(), + buf.size(), flags); return detail::maybe_flag_fixed_fd(std::move(op), sockfd); } @@ -629,8 +642,8 @@ inline auto async_recv(Fd sockfd, Buffer &&buf, int flags) { */ template inline auto async_recv(Fd sockfd, Buffer &buf, int flags) { - auto op = make_select_buffer_op_awaiter(&buf, io_uring_prep_recv, sockfd, - nullptr, 0, flags); + auto op = detail::make_select_buffer_op_awaiter(&buf, io_uring_prep_recv, + sockfd, nullptr, 0, flags); return detail::maybe_flag_fixed_fd(std::move(op), sockfd); } @@ -640,8 +653,8 @@ inline auto async_recv(Fd sockfd, Buffer &buf, int flags) { */ template inline auto async_recv(Fd sockfd, Buffer &buf, int flags) { - auto op = make_bundle_select_buffer_op_awaiter(&buf, io_uring_prep_recv, - sockfd, nullptr, 0, flags); + auto op = detail::make_bundle_select_buffer_op_awaiter( + &buf, io_uring_prep_recv, sockfd, nullptr, 0, flags); return detail::maybe_flag_fixed_fd(std::move(op), sockfd); } #endif @@ -652,7 +665,7 @@ inline auto async_recv(Fd sockfd, Buffer &buf, int flags) { template inline auto async_recv_multishot(Fd sockfd, Buffer &buf, int flags, MultiShotFunc &&func) { - auto op = make_multishot_select_buffer_op_awaiter( + auto op = detail::make_multishot_select_buffer_op_awaiter( std::forward(func), &buf, io_uring_prep_recv_multishot, sockfd, nullptr, 0, flags); return detail::maybe_flag_fixed_fd(std::move(op), sockfd); @@ -665,7 +678,7 @@ inline auto async_recv_multishot(Fd sockfd, Buffer &buf, int flags, template inline auto async_recv_multishot(Fd sockfd, Buffer &buf, int flags, MultiShotFunc &&func) { - auto op = make_multishot_bundle_select_buffer_op_awaiter( + auto op = detail::make_multishot_bundle_select_buffer_op_awaiter( std::forward(func), &buf, io_uring_prep_recv_multishot, sockfd, nullptr, 0, flags); return detail::maybe_flag_fixed_fd(std::move(op), sockfd); @@ -676,7 +689,7 @@ inline auto async_recv_multishot(Fd sockfd, Buffer &buf, int flags, * @brief See io_uring_prep_openat2 */ inline auto async_openat2(int dfd, const char *path, struct open_how *how) { - return make_op_awaiter(io_uring_prep_openat2, dfd, path, how); + return detail::make_op_awaiter(io_uring_prep_openat2, dfd, path, how); } /** @@ -684,15 +697,15 @@ inline auto async_openat2(int dfd, const char *path, struct open_how *how) { */ inline auto async_openat2_direct(int dfd, const char *path, struct open_how *how, unsigned file_index) { - return make_op_awaiter(io_uring_prep_openat2_direct, dfd, path, how, - file_index); + return detail::make_op_awaiter(io_uring_prep_openat2_direct, dfd, path, how, + file_index); } /** * @brief See io_uring_prep_shutdown */ template inline auto async_shutdown(Fd fd, int how) { - auto op = make_op_awaiter(io_uring_prep_shutdown, fd, how); + auto op = detail::make_op_awaiter(io_uring_prep_shutdown, fd, how); return detail::maybe_flag_fixed_fd(std::move(op), fd); } @@ -700,7 +713,7 @@ template inline auto async_shutdown(Fd fd, int how) { * @brief See io_uring_prep_unlinkat */ inline auto async_unlinkat(int dfd, const char *path, int flags) { - return make_op_awaiter(io_uring_prep_unlinkat, dfd, path, flags); + return detail::make_op_awaiter(io_uring_prep_unlinkat, dfd, path, flags); } /** @@ -715,8 +728,8 @@ inline auto async_unlink(const char *path, int flags) { */ inline auto async_renameat(int olddfd, const char *oldpath, int newdfd, const char *newpath, unsigned int flags) { - return make_op_awaiter(io_uring_prep_renameat, olddfd, oldpath, newdfd, - newpath, flags); + return detail::make_op_awaiter(io_uring_prep_renameat, olddfd, oldpath, + newdfd, newpath, flags); } /** @@ -732,8 +745,8 @@ inline auto async_rename(const char *oldpath, const char *newpath) { template inline auto async_sync_file_range(Fd fd, unsigned len, __u64 offset, int flags) { - auto op = - make_op_awaiter(io_uring_prep_sync_file_range, fd, len, offset, flags); + auto op = detail::make_op_awaiter(io_uring_prep_sync_file_range, fd, len, + offset, flags); return detail::maybe_flag_fixed_fd(std::move(op), fd); } @@ -741,7 +754,7 @@ inline auto async_sync_file_range(Fd fd, unsigned len, __u64 offset, * @brief See io_uring_prep_mkdirat */ inline auto async_mkdirat(int dfd, const char *path, mode_t mode) { - return make_op_awaiter(io_uring_prep_mkdirat, dfd, path, mode); + return detail::make_op_awaiter(io_uring_prep_mkdirat, dfd, path, mode); } /** @@ -756,7 +769,8 @@ inline auto async_mkdir(const char *path, mode_t mode) { */ inline auto async_symlinkat(const char *target, int newdirfd, const char *linkpath) { - return make_op_awaiter(io_uring_prep_symlinkat, target, newdirfd, linkpath); + return detail::make_op_awaiter(io_uring_prep_symlinkat, target, newdirfd, + linkpath); } /** @@ -771,8 +785,8 @@ inline auto async_symlink(const char *target, const char *linkpath) { */ inline auto async_linkat(int olddfd, const char *oldpath, int newdfd, const char *newpath, int flags) { - return make_op_awaiter(io_uring_prep_linkat, olddfd, oldpath, newdfd, - newpath, flags); + return detail::make_op_awaiter(io_uring_prep_linkat, olddfd, oldpath, + newdfd, newpath, flags); } /** @@ -787,7 +801,8 @@ inline auto async_link(const char *oldpath, const char *newpath, int flags) { */ inline auto async_getxattr(const char *name, char *value, const char *path, unsigned int len) { - return make_op_awaiter(io_uring_prep_getxattr, name, value, path, len); + return detail::make_op_awaiter(io_uring_prep_getxattr, name, value, path, + len); } /** @@ -795,8 +810,8 @@ inline auto async_getxattr(const char *name, char *value, const char *path, */ inline auto async_setxattr(const char *name, const char *value, const char *path, int flags, unsigned int len) { - return make_op_awaiter(io_uring_prep_setxattr, name, value, path, flags, - len); + return detail::make_op_awaiter(io_uring_prep_setxattr, name, value, path, + flags, len); } /** @@ -804,7 +819,8 @@ inline auto async_setxattr(const char *name, const char *value, */ inline auto async_fgetxattr(int fd, const char *name, char *value, unsigned int len) { - return make_op_awaiter(io_uring_prep_fgetxattr, fd, name, value, len); + return detail::make_op_awaiter(io_uring_prep_fgetxattr, fd, name, value, + len); } /** @@ -812,8 +828,8 @@ inline auto async_fgetxattr(int fd, const char *name, char *value, */ inline auto async_fsetxattr(int fd, const char *name, const char *value, int flags, unsigned int len) { - return make_op_awaiter(io_uring_prep_fsetxattr, fd, name, value, flags, - len); + return detail::make_op_awaiter(io_uring_prep_fsetxattr, fd, name, value, + flags, len); } /** @@ -821,7 +837,8 @@ inline auto async_fsetxattr(int fd, const char *name, const char *value, */ inline auto async_socket(int domain, int type, int protocol, unsigned int flags) { - return make_op_awaiter(io_uring_prep_socket, domain, type, protocol, flags); + return detail::make_op_awaiter(io_uring_prep_socket, domain, type, protocol, + flags); } /** @@ -829,8 +846,8 @@ inline auto async_socket(int domain, int type, int protocol, */ inline auto async_socket_direct(int domain, int type, int protocol, unsigned file_index, unsigned int flags) { - return make_op_awaiter(io_uring_prep_socket_direct, domain, type, protocol, - file_index, flags); + return detail::make_op_awaiter(io_uring_prep_socket_direct, domain, type, + protocol, file_index, flags); } #if !IO_URING_CHECK_VERSION(2, 5) // >= 2.5 @@ -840,8 +857,8 @@ inline auto async_socket_direct(int domain, int type, int protocol, template inline auto async_cmd_sock(int cmd_op, Fd fd, int level, int optname, void *optval, int optlen) { - auto op = make_op_awaiter(io_uring_prep_cmd_sock, cmd_op, fd, level, - optname, optval, optlen); + auto op = detail::make_op_awaiter(io_uring_prep_cmd_sock, cmd_op, fd, level, + optname, optval, optlen); return detail::maybe_flag_fixed_fd(std::move(op), fd); } #endif @@ -853,8 +870,8 @@ inline auto async_cmd_sock(int cmd_op, Fd fd, int level, int optname, 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); + auto op = detail::make_op_awaiter(io_uring_prep_cmd_getsockname, fd, + sockaddr, sockaddr_len, peer); return detail::maybe_flag_fixed_fd(std::move(op), fd); } #endif @@ -865,8 +882,8 @@ inline auto async_cmd_getsockname(Fd fd, struct sockaddr *sockaddr, */ inline auto async_waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options, unsigned int flags) { - return make_op_awaiter(io_uring_prep_waitid, idtype, id, infop, options, - flags); + return detail::make_op_awaiter(io_uring_prep_waitid, idtype, id, infop, + options, flags); } #endif @@ -876,8 +893,8 @@ inline auto async_waitid(idtype_t idtype, id_t id, siginfo_t *infop, */ inline auto async_futex_wake(uint32_t *futex, uint64_t val, uint64_t mask, uint32_t futex_flags, unsigned int flags) { - return make_op_awaiter(io_uring_prep_futex_wake, futex, val, mask, - futex_flags, flags); + return detail::make_op_awaiter(io_uring_prep_futex_wake, futex, val, mask, + futex_flags, flags); } #endif @@ -887,8 +904,8 @@ inline auto async_futex_wake(uint32_t *futex, uint64_t val, uint64_t mask, */ inline auto async_futex_wait(uint32_t *futex, uint64_t val, uint64_t mask, uint32_t futex_flags, unsigned int flags) { - return make_op_awaiter(io_uring_prep_futex_wait, futex, val, mask, - futex_flags, flags); + return detail::make_op_awaiter(io_uring_prep_futex_wait, futex, val, mask, + futex_flags, flags); } #endif @@ -898,7 +915,8 @@ inline auto async_futex_wait(uint32_t *futex, uint64_t val, uint64_t mask, */ inline auto async_futex_waitv(struct futex_waitv *futex, uint32_t nr_futex, unsigned int flags) { - return make_op_awaiter(io_uring_prep_futex_waitv, futex, nr_futex, flags); + return detail::make_op_awaiter(io_uring_prep_futex_waitv, futex, nr_futex, + flags); } #endif @@ -907,7 +925,8 @@ inline auto async_futex_waitv(struct futex_waitv *futex, uint32_t nr_futex, * @brief See io_uring_prep_fixed_fd_install */ inline auto async_fixed_fd_install(int fixed_fd, unsigned int flags) { - return make_op_awaiter(io_uring_prep_fixed_fd_install, fixed_fd, flags); + return detail::make_op_awaiter(io_uring_prep_fixed_fd_install, fixed_fd, + flags); } #endif @@ -922,7 +941,7 @@ inline auto async_fixed_fd_send(FdTable &dst, int source_fd, int target_fd, // NOLINTNEXTLINE(performance-no-int-to-ptr) payload = reinterpret_cast((target_fd + 1) << 3); } - return make_op_awaiter( + return detail::make_op_awaiter( io_uring_prep_msg_ring_fd, dst.ring_.ring_fd, source_fd, target_fd, reinterpret_cast(encode_work(payload, WorkType::SendFd)), flags); @@ -934,7 +953,7 @@ inline auto async_fixed_fd_send(FdTable &dst, int source_fd, int target_fd, * @brief See io_uring_prep_ftruncate */ template inline auto async_ftruncate(Fd fd, loff_t len) { - auto op = make_op_awaiter(io_uring_prep_ftruncate, fd, len); + auto op = detail::make_op_awaiter(io_uring_prep_ftruncate, fd, len); return detail::maybe_flag_fixed_fd(std::move(op), fd); } #endif @@ -945,7 +964,8 @@ template inline auto async_ftruncate(Fd fd, loff_t len) { */ template inline auto async_cmd_discard(Fd fd, uint64_t offset, uint64_t nbytes) { - auto op = make_op_awaiter(io_uring_prep_cmd_discard, fd, offset, nbytes); + auto op = + detail::make_op_awaiter(io_uring_prep_cmd_discard, fd, offset, nbytes); return detail::maybe_flag_fixed_fd(std::move(op), fd); } #endif @@ -956,7 +976,7 @@ inline auto async_cmd_discard(Fd fd, uint64_t offset, uint64_t nbytes) { */ template inline auto async_bind(Fd fd, struct sockaddr *addr, socklen_t addrlen) { - auto op = make_op_awaiter(io_uring_prep_bind, fd, addr, addrlen); + auto op = detail::make_op_awaiter(io_uring_prep_bind, fd, addr, addrlen); return detail::maybe_flag_fixed_fd(std::move(op), fd); } #endif @@ -966,7 +986,7 @@ inline auto async_bind(Fd fd, struct sockaddr *addr, socklen_t addrlen) { * @brief See io_uring_prep_listen */ template inline auto async_listen(Fd fd, int backlog) { - auto op = make_op_awaiter(io_uring_prep_listen, fd, backlog); + auto op = detail::make_op_awaiter(io_uring_prep_listen, fd, backlog); return detail::maybe_flag_fixed_fd(std::move(op), fd); } #endif @@ -975,7 +995,7 @@ template inline auto async_listen(Fd fd, int backlog) { * @brief See io_uring_prep_epoll_ctl */ inline auto async_epoll_ctl(int epfd, int fd, int op, struct epoll_event *ev) { - return make_op_awaiter(io_uring_prep_epoll_ctl, epfd, fd, op, ev); + return detail::make_op_awaiter(io_uring_prep_epoll_ctl, epfd, fd, op, ev); } #if !IO_URING_CHECK_VERSION(2, 10) // >= 2.10 @@ -984,8 +1004,8 @@ inline auto async_epoll_ctl(int epfd, int fd, int op, struct epoll_event *ev) { */ inline auto async_epoll_wait(int fd, struct epoll_event *events, int maxevents, unsigned flags) { - return make_op_awaiter(io_uring_prep_epoll_wait, fd, events, maxevents, - flags); + return detail::make_op_awaiter(io_uring_prep_epoll_wait, fd, events, + maxevents, flags); } #endif @@ -994,7 +1014,7 @@ inline auto async_epoll_wait(int fd, struct epoll_event *events, int maxevents, * @brief See io_uring_prep_pipe */ inline auto async_pipe(int *fds, int pipe_flags) { - return make_op_awaiter(io_uring_prep_pipe, fds, pipe_flags); + return detail::make_op_awaiter(io_uring_prep_pipe, fds, pipe_flags); } #endif @@ -1004,8 +1024,8 @@ inline auto async_pipe(int *fds, int pipe_flags) { */ inline auto async_pipe_direct(int *fds, int pipe_flags, unsigned int file_index) { - return make_op_awaiter(io_uring_prep_pipe_direct, fds, pipe_flags, - file_index); + return detail::make_op_awaiter(io_uring_prep_pipe_direct, fds, pipe_flags, + file_index); } #endif diff --git a/tests/test_awaiter_operations.cpp b/tests/test_awaiter_operations.cpp index 392774ba..80181209 100644 --- a/tests/test_awaiter_operations.cpp +++ b/tests/test_awaiter_operations.cpp @@ -43,7 +43,7 @@ TEST_CASE("test awaiter_operations - test make_op_awaiter") { size_t unfinished = 1; auto func = [&]() -> condy::Coro { - co_await condy::make_op_awaiter(io_uring_prep_nop); + co_await condy::detail::make_op_awaiter(io_uring_prep_nop); --unfinished; }; @@ -69,9 +69,9 @@ TEST_CASE("test awaiter_operations - test when_all") { size_t unfinished = 1; auto func = [&]() -> condy::Coro { - auto aw1 = condy::make_op_awaiter(io_uring_prep_nop); - auto aw2 = condy::make_op_awaiter(io_uring_prep_nop); - auto aw3 = condy::make_op_awaiter(io_uring_prep_nop); + auto aw1 = condy::detail::make_op_awaiter(io_uring_prep_nop); + auto aw2 = condy::detail::make_op_awaiter(io_uring_prep_nop); + auto aw3 = condy::detail::make_op_awaiter(io_uring_prep_nop); auto [r1, r2, r3] = co_await condy::when_all( std::move(aw1), std::move(aw2), std::move(aw3)); REQUIRE(r1 == 0); @@ -106,9 +106,11 @@ TEST_CASE("test awaiter_operations - test when_any") { .tv_sec = 60, .tv_nsec = 0, }; - auto aw1 = condy::make_op_awaiter(io_uring_prep_timeout, &ts, 0, 0); - auto aw2 = condy::make_op_awaiter(io_uring_prep_nop); - auto aw3 = condy::make_op_awaiter(io_uring_prep_timeout, &ts, 0, 0); + auto aw1 = + condy::detail::make_op_awaiter(io_uring_prep_timeout, &ts, 0, 0); + auto aw2 = condy::detail::make_op_awaiter(io_uring_prep_nop); + auto aw3 = + condy::detail::make_op_awaiter(io_uring_prep_timeout, &ts, 0, 0); auto r = co_await condy::when_any(std::move(aw1), std::move(aw2), std::move(aw3)); REQUIRE(r.index() == 1); @@ -137,9 +139,9 @@ TEST_CASE("test awaiter_operations - test ranged when_all") { size_t unfinished = 1; auto func = [&]() -> condy::Coro { - auto aw1 = condy::make_op_awaiter(io_uring_prep_nop); - auto aw2 = condy::make_op_awaiter(io_uring_prep_nop); - auto aw3 = condy::make_op_awaiter(io_uring_prep_nop); + auto aw1 = condy::detail::make_op_awaiter(io_uring_prep_nop); + auto aw2 = condy::detail::make_op_awaiter(io_uring_prep_nop); + auto aw3 = condy::detail::make_op_awaiter(io_uring_prep_nop); std::vector awaiters; awaiters.emplace_back(std::move(aw1)); awaiters.emplace_back(std::move(aw2)); @@ -180,9 +182,12 @@ TEST_CASE("test awaiter_operations - test ranged when_any") { .tv_sec = 0, .tv_nsec = 100, }; - auto aw1 = condy::make_op_awaiter(io_uring_prep_timeout, &ts1, 0, 0); - auto aw2 = condy::make_op_awaiter(io_uring_prep_timeout, &ts2, 0, 0); - auto aw3 = condy::make_op_awaiter(io_uring_prep_timeout, &ts1, 0, 0); + auto aw1 = + condy::detail::make_op_awaiter(io_uring_prep_timeout, &ts1, 0, 0); + auto aw2 = + condy::detail::make_op_awaiter(io_uring_prep_timeout, &ts2, 0, 0); + auto aw3 = + condy::detail::make_op_awaiter(io_uring_prep_timeout, &ts1, 0, 0); std::vector awaiters; awaiters.emplace_back(std::move(aw1)); awaiters.emplace_back(std::move(aw2)); @@ -214,9 +219,9 @@ TEST_CASE("test awaiter_operations - test &&") { size_t unfinished = 1; auto func = [&]() -> condy::Coro { - auto aw1 = condy::make_op_awaiter(io_uring_prep_nop); - auto aw2 = condy::make_op_awaiter(io_uring_prep_nop); - auto aw3 = condy::make_op_awaiter(io_uring_prep_nop); + auto aw1 = condy::detail::make_op_awaiter(io_uring_prep_nop); + auto aw2 = condy::detail::make_op_awaiter(io_uring_prep_nop); + auto aw3 = condy::detail::make_op_awaiter(io_uring_prep_nop); auto [r1, r2, r3] = co_await (std::move(aw1) && std::move(aw2) && std::move(aw3)); REQUIRE(r1 == 0); @@ -251,9 +256,11 @@ TEST_CASE("test awaiter_operations - test ||") { .tv_sec = 60, .tv_nsec = 0, }; - auto aw1 = condy::make_op_awaiter(io_uring_prep_timeout, &ts, 0, 0); - auto aw2 = condy::make_op_awaiter(io_uring_prep_nop); - auto aw3 = condy::make_op_awaiter(io_uring_prep_timeout, &ts, 0, 0); + auto aw1 = + condy::detail::make_op_awaiter(io_uring_prep_timeout, &ts, 0, 0); + auto aw2 = condy::detail::make_op_awaiter(io_uring_prep_nop); + auto aw3 = + condy::detail::make_op_awaiter(io_uring_prep_timeout, &ts, 0, 0); auto r = co_await (std::move(aw1) || std::move(aw2) || std::move(aw3)); REQUIRE(r.index() == 1); --unfinished; @@ -285,10 +292,12 @@ TEST_CASE("test awaiter_operations - mixed && and ||") { .tv_sec = 60, .tv_nsec = 0, }; - auto aw1 = condy::make_op_awaiter(io_uring_prep_timeout, &ts, 0, 0); - auto aw2 = condy::make_op_awaiter(io_uring_prep_nop); - auto aw3 = condy::make_op_awaiter(io_uring_prep_nop); - auto aw4 = condy::make_op_awaiter(io_uring_prep_timeout, &ts, 0, 0); + auto aw1 = + condy::detail::make_op_awaiter(io_uring_prep_timeout, &ts, 0, 0); + auto aw2 = condy::detail::make_op_awaiter(io_uring_prep_nop); + auto aw3 = condy::detail::make_op_awaiter(io_uring_prep_nop); + auto aw4 = + condy::detail::make_op_awaiter(io_uring_prep_timeout, &ts, 0, 0); auto [r1, r2] = co_await ((std::move(aw1) || std::move(aw2)) && (std::move(aw3) || std::move(aw4))); REQUIRE(r1.index() == 1); @@ -318,9 +327,9 @@ TEST_CASE("test awaiter_operations - ranged awaiter push") { size_t unfinished = 1; auto func = [&]() -> condy::Coro { - auto aw1 = condy::make_op_awaiter(io_uring_prep_nop); - auto aw2 = condy::make_op_awaiter(io_uring_prep_nop); - auto aw3 = condy::make_op_awaiter(io_uring_prep_nop); + auto aw1 = condy::detail::make_op_awaiter(io_uring_prep_nop); + auto aw2 = condy::detail::make_op_awaiter(io_uring_prep_nop); + auto aw3 = condy::detail::make_op_awaiter(io_uring_prep_nop); auto awaiter = condy::when_all(std::vector{}); awaiter.push(std::move(aw1)); awaiter.push(std::move(aw2)); @@ -357,9 +366,10 @@ TEST_CASE("test awaiter_operations - test link") { .tv_sec = 0, .tv_nsec = 100, }; - auto aw1 = condy::make_op_awaiter(io_uring_prep_nop); - auto aw2 = condy::make_op_awaiter(io_uring_prep_timeout, &ts, 0, 0); - auto aw3 = condy::make_op_awaiter(io_uring_prep_nop); + auto aw1 = condy::detail::make_op_awaiter(io_uring_prep_nop); + auto aw2 = + condy::detail::make_op_awaiter(io_uring_prep_timeout, &ts, 0, 0); + auto aw3 = condy::detail::make_op_awaiter(io_uring_prep_nop); auto [r1, r2, r3] = co_await condy::link(std::move(aw1), std::move(aw2), std::move(aw3)); REQUIRE(r1 == 0); @@ -394,9 +404,10 @@ TEST_CASE("test awaiter_operations - test >>") { .tv_sec = 0, .tv_nsec = 100, }; - auto aw1 = condy::make_op_awaiter(io_uring_prep_nop); - auto aw2 = condy::make_op_awaiter(io_uring_prep_timeout, &ts, 0, 0); - auto aw3 = condy::make_op_awaiter(io_uring_prep_nop); + auto aw1 = condy::detail::make_op_awaiter(io_uring_prep_nop); + auto aw2 = + condy::detail::make_op_awaiter(io_uring_prep_timeout, &ts, 0, 0); + auto aw3 = condy::detail::make_op_awaiter(io_uring_prep_nop); auto [r1, r2, r3] = co_await (std::move(aw1) >> std::move(aw2) >> std::move(aw3)); REQUIRE(r1 == 0); @@ -427,7 +438,7 @@ TEST_CASE("test awaiter_operations - test drain") { size_t unfinished = 1; auto func = [&]() -> condy::Coro { - auto aw = condy::make_op_awaiter(io_uring_prep_nop); + auto aw = condy::detail::make_op_awaiter(io_uring_prep_nop); co_await condy::drain(std::move(aw)); --unfinished; }; @@ -454,9 +465,9 @@ TEST_CASE("test awaiter_operations - test drain with when_all") { size_t unfinished = 1; auto func = [&]() -> condy::Coro { - auto aw1 = condy::make_op_awaiter(io_uring_prep_nop); - auto aw2 = condy::make_op_awaiter(io_uring_prep_nop); - auto aw3 = condy::make_op_awaiter(io_uring_prep_nop); + auto aw1 = condy::detail::make_op_awaiter(io_uring_prep_nop); + auto aw2 = condy::detail::make_op_awaiter(io_uring_prep_nop); + auto aw3 = condy::detail::make_op_awaiter(io_uring_prep_nop); co_await (std::move(aw1) && std::move(aw2) && condy::drain(std::move(aw3))); --unfinished; @@ -484,9 +495,9 @@ TEST_CASE("test awaiter_operations - test parallel all") { size_t unfinished = 1; auto func = [&]() -> condy::Coro { - auto aw1 = condy::make_op_awaiter(io_uring_prep_nop); - auto aw2 = condy::make_op_awaiter(io_uring_prep_nop); - auto aw3 = condy::make_op_awaiter(io_uring_prep_nop); + auto aw1 = condy::detail::make_op_awaiter(io_uring_prep_nop); + auto aw2 = condy::detail::make_op_awaiter(io_uring_prep_nop); + auto aw3 = condy::detail::make_op_awaiter(io_uring_prep_nop); auto [order, results] = co_await condy::parallel( std::move(aw1), std::move(aw2), std::move(aw3)); diff --git a/tests/test_buffer_table.cpp b/tests/test_buffer_table.cpp index 6a9086d5..8abc01c5 100644 --- a/tests/test_buffer_table.cpp +++ b/tests/test_buffer_table.cpp @@ -76,14 +76,14 @@ TEST_CASE("test buffer_table - use registered buffer") { buffer_table.update(0, iovs, 2); auto write_op = - condy::make_op_awaiter(io_uring_prep_write_fixed, pipes[1], - write_buf, sizeof(write_buf), 0, 1); + condy::detail::make_op_awaiter(io_uring_prep_write_fixed, pipes[1], + write_buf, sizeof(write_buf), 0, 1); int write_res = co_await write_op; REQUIRE(write_res == sizeof(write_buf)); auto read_op = - condy::make_op_awaiter(io_uring_prep_read_fixed, pipes[0], read_buf, - sizeof(read_buf), 0, 0); + condy::detail::make_op_awaiter(io_uring_prep_read_fixed, pipes[0], + read_buf, sizeof(read_buf), 0, 0); int read_res = co_await read_op; REQUIRE(read_res == sizeof(read_buf)); REQUIRE(std::memcmp(write_buf, read_buf, sizeof(write_buf)) == 0); diff --git a/tests/test_fd_table.cpp b/tests/test_fd_table.cpp index c62868dc..3b575890 100644 --- a/tests/test_fd_table.cpp +++ b/tests/test_fd_table.cpp @@ -60,14 +60,14 @@ TEST_CASE("test fd_table - use fixed fd") { char write_buf[] = "hello"; char read_buf[sizeof(write_buf)] = {0}; - auto write_op = condy::make_op_awaiter(io_uring_prep_write, 1, - write_buf, sizeof(write_buf), 0); + auto write_op = condy::detail::make_op_awaiter( + io_uring_prep_write, 1, write_buf, sizeof(write_buf), 0); int write_res = co_await condy::flag(std::move(write_op)); REQUIRE(write_res == sizeof(write_buf)); - auto read_op = condy::make_op_awaiter(io_uring_prep_read, 0, read_buf, - sizeof(read_buf), 0); + auto read_op = condy::detail::make_op_awaiter( + io_uring_prep_read, 0, read_buf, sizeof(read_buf), 0); int read_res = co_await condy::flag(std::move(read_op)); REQUIRE(read_res == sizeof(read_buf)); diff --git a/tests/test_op_awaiter.cpp b/tests/test_op_awaiter.cpp index a2f7acda..b5a7b9e0 100644 --- a/tests/test_op_awaiter.cpp +++ b/tests/test_op_awaiter.cpp @@ -40,7 +40,7 @@ TEST_CASE("test op_awaiter - basic routine") { size_t unfinished = 1; auto func = [&]() -> condy::Coro { - co_await condy::make_op_awaiter(io_uring_prep_nop); + co_await condy::detail::make_op_awaiter(io_uring_prep_nop); --unfinished; }; @@ -66,8 +66,8 @@ TEST_CASE("test op_awaiter - multiple ops") { size_t unfinished = 1; auto func = [&]() -> condy::Coro { - co_await condy::make_op_awaiter(io_uring_prep_nop); - co_await condy::make_op_awaiter(io_uring_prep_nop); + co_await condy::detail::make_op_awaiter(io_uring_prep_nop); + co_await condy::detail::make_op_awaiter(io_uring_prep_nop); --unfinished; }; @@ -93,8 +93,8 @@ TEST_CASE("test op_awaiter - concurrent op") { size_t unfinished = 1; auto func = [&]() -> condy::Coro { - auto awaiter1 = condy::make_op_awaiter(io_uring_prep_nop); - auto awaiter2 = condy::make_op_awaiter(io_uring_prep_nop); + auto awaiter1 = condy::detail::make_op_awaiter(io_uring_prep_nop); + auto awaiter2 = condy::detail::make_op_awaiter(io_uring_prep_nop); auto [r1, r2] = co_await condy::WhenAllAwaiter( std::move(awaiter1), std::move(awaiter2)); @@ -130,8 +130,8 @@ TEST_CASE("test op_awaiter - cancel op") { .tv_nsec = 0, }; auto awaiter1 = - condy::make_op_awaiter(io_uring_prep_timeout, &ts, 0, 0); - auto awaiter2 = condy::make_op_awaiter(io_uring_prep_nop); + condy::detail::make_op_awaiter(io_uring_prep_timeout, &ts, 0, 0); + auto awaiter2 = condy::detail::make_op_awaiter(io_uring_prep_nop); auto awaiter = condy::WhenAnyAwaiter( std::move(awaiter1), std::move(awaiter2)); @@ -195,7 +195,7 @@ TEST_CASE("test op_awaiter - multishot op") { size_t unfinished = 1; auto func = [&]() -> condy::Coro { - co_await condy::make_multishot_op_awaiter( + co_await condy::detail::make_multishot_op_awaiter( [&](int res) { auto coro = handle_multishot(res); coro.release().resume(); @@ -236,8 +236,9 @@ TEST_CASE("test op_awaiter - select buffer op") { size_t unfinished = 1; auto func = [&]() -> condy::Coro { - auto [res, buf] = co_await condy::make_select_buffer_op_awaiter( - &pool, io_uring_prep_read, pipefd[0], nullptr, 0, 0); + auto [res, buf] = + co_await condy::detail::make_select_buffer_op_awaiter( + &pool, io_uring_prep_read, pipefd[0], nullptr, 0, 0); REQUIRE(res >= 0); REQUIRE(buf.size() == 32); REQUIRE(std::memcmp(buf.data(), "test", 4) == 0); diff --git a/tests/test_runtime.cpp b/tests/test_runtime.cpp index d4b2b3fd..5d141975 100644 --- a/tests/test_runtime.cpp +++ b/tests/test_runtime.cpp @@ -102,7 +102,7 @@ TEST_CASE("test runtime - single thread schedule coroutines with operation") { condy::Runtime runtime(options); auto func = [](int &flag) -> condy::Coro { - co_await condy::make_op_awaiter(io_uring_prep_nop); + co_await condy::detail::make_op_awaiter(io_uring_prep_nop); flag = 1; }; @@ -133,8 +133,8 @@ TEST_CASE("test runtime - single thread schedule coroutines with parallel " condy::Runtime runtime(options); auto func = [](int &flag) -> condy::Coro { - co_await (condy::make_op_awaiter(io_uring_prep_nop) >> - condy::make_op_awaiter(io_uring_prep_nop)); + co_await (condy::detail::make_op_awaiter(io_uring_prep_nop) >> + condy::detail::make_op_awaiter(io_uring_prep_nop)); flag = 1; }; @@ -171,8 +171,8 @@ TEST_CASE("test runtime - single thread schedule coroutine with cancel") { .tv_nsec = 0, }; auto r = co_await ( - condy::make_op_awaiter(io_uring_prep_timeout, &ts, 0, 0) || - condy::make_op_awaiter(io_uring_prep_nop)); + condy::detail::make_op_awaiter(io_uring_prep_timeout, &ts, 0, 0) || + condy::detail::make_op_awaiter(io_uring_prep_nop)); REQUIRE(r.index() == 1); // nop path finished = true; co_return; diff --git a/tests/test_task.cpp b/tests/test_task.cpp index c008a51c..28ad3243 100644 --- a/tests/test_task.cpp +++ b/tests/test_task.cpp @@ -109,7 +109,7 @@ TEST_CASE("test task - launch multiple tasks") { bool finished = false; auto sub_func = [&](int v, int &r) -> condy::Coro { - co_await condy::make_op_awaiter(io_uring_prep_nop); + co_await condy::detail::make_op_awaiter(io_uring_prep_nop); r = v; }; @@ -141,7 +141,7 @@ TEST_CASE("test task - return value") { bool finished = false; auto sub_func = [](int v) -> condy::Coro { - co_await condy::make_op_awaiter(io_uring_prep_nop); + co_await condy::detail::make_op_awaiter(io_uring_prep_nop); co_return v; }; @@ -176,7 +176,8 @@ TEST_CASE("test task - return value with wait") { .tv_sec = 0, .tv_nsec = 1000000, // 1ms }; - co_await condy::make_op_awaiter(io_uring_prep_timeout, &ts, 0, 0); + co_await condy::detail::make_op_awaiter(io_uring_prep_timeout, &ts, 0, + 0); finished = true; co_return 42; }; @@ -196,7 +197,7 @@ TEST_CASE("test task - exception propagation") { condy::Runtime runtime(options); auto func = [&]() -> condy::Coro { - co_await condy::make_op_awaiter(io_uring_prep_nop); + co_await condy::detail::make_op_awaiter(io_uring_prep_nop); throw std::runtime_error("Test exception"); }; @@ -262,7 +263,7 @@ TEST_CASE("test task - run in different thread") { TEST_CASE("test task - spawn from no runtime") { size_t count = 0; auto func = [&]() -> condy::Coro { - co_await condy::make_op_awaiter(io_uring_prep_nop); + co_await condy::detail::make_op_awaiter(io_uring_prep_nop); count++; co_return; }; @@ -293,7 +294,7 @@ TEST_CASE("test task - detach") { bool finished = false; auto func = [&]() -> condy::Coro { - co_await condy::make_op_awaiter(io_uring_prep_nop); + co_await condy::detail::make_op_awaiter(io_uring_prep_nop); finished = true; co_return; }; From 0dfa204227ebbf4e6b25a08603b157bc14f29361 Mon Sep 17 00:00:00 2001 From: wokron Date: Thu, 12 Feb 2026 18:37:07 +0800 Subject: [PATCH 4/5] add docs --- include/condy/awaiter_operations.hpp | 35 ++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/include/condy/awaiter_operations.hpp b/include/condy/awaiter_operations.hpp index 7dcabd4a..a1deb614 100644 --- a/include/condy/awaiter_operations.hpp +++ b/include/condy/awaiter_operations.hpp @@ -16,12 +16,35 @@ namespace condy { +/** + * @brief Build a single-shot operation awaiter with custom CQE handler. + * @tparam CQEHandler Type of CQE handler. + * @tparam PrepFunc Type of preparation function. + * @tparam Args Additional arguments for CQE handler construction. + * @param func Preparation function that accepts `Ring*` and returns + * `io_uring_sqe*`. + * @param handler_args Arguments forwarded to CQE handler constructor. + * @return OpAwaiter The constructed awaiter. + */ template auto build_op_awaiter(PrepFunc &&func, Args &&...handler_args) { return OpAwaiter, CQEHandler>( std::forward(func), std::forward(handler_args)...); } +/** + * @brief Build a multi-shot operation awaiter with custom CQE handler. + * @tparam CQEHandler Type of CQE handler. + * @tparam PrepFunc Type of preparation function. + * @tparam MultiShotFunc Type of callback function for multi-shot operations. + * @tparam Args Additional arguments for CQE handler construction. + * @param func Preparation function that accepts `Ring*` and returns + * `io_uring_sqe*`. + * @param multishot_func Callback invoked on each completion except the last + * one. + * @param handler_args Arguments forwarded to CQE handler constructor. + * @return MultiShotOpAwaiter The constructed awaiter. + */ template auto build_multishot_op_awaiter(PrepFunc &&func, MultiShotFunc &&multishot_func, @@ -33,6 +56,18 @@ auto build_multishot_op_awaiter(PrepFunc &&func, MultiShotFunc &&multishot_func, std::forward(handler_args)...); } +/** + * @brief Build a zero-copy operation awaiter with custom CQE handler. + * @tparam CQEHandler Type of CQE handler. + * @tparam PrepFunc Type of preparation function. + * @tparam FreeFunc Type of resource cleanup function. + * @tparam Args Additional arguments for CQE handler construction. + * @param func Preparation function that accepts `Ring*` and returns + * `io_uring_sqe*`. + * @param free_func Cleanup function invoked when resource no longer needed. + * @param handler_args Arguments forwarded to CQE handler constructor. + * @return ZeroCopyOpAwaiter The constructed awaiter. + */ template auto build_zero_copy_op_awaiter(PrepFunc &&func, FreeFunc &&free_func, From 208a3aa8edb872fe95f4686b9d219278c180c1a4 Mon Sep 17 00:00:00 2001 From: wokron Date: Thu, 12 Feb 2026 18:40:36 +0800 Subject: [PATCH 5/5] add CQEHandler docs --- include/condy/cqe_handler.hpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/condy/cqe_handler.hpp b/include/condy/cqe_handler.hpp index 486ef96b..0bc790ef 100644 --- a/include/condy/cqe_handler.hpp +++ b/include/condy/cqe_handler.hpp @@ -16,6 +16,10 @@ namespace condy { +/** + * @brief A simple CQE handler that extracts the result from the CQE without any + * additional processing. + */ class SimpleCQEHandler { public: using ReturnType = int32_t; @@ -28,6 +32,11 @@ class SimpleCQEHandler { int32_t res_ = -ENOTRECOVERABLE; // Internal error if not set }; +/** + * @brief A CQE handler that returns the selected buffers based on the result of + * the CQE. + * @tparam Br The buffer ring type + */ template class SelectBufferCQEHandler { public: using ReturnType = std::pair;