Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions examples/fuse-prime-fs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,8 @@ auto fuse_register_cmd(iovec iov[2], uint16_t qid) {
auto *cmd = reinterpret_cast<fuse_uring_cmd_req *>(sqe->cmd);
*cmd = {};
cmd->qid = qid;
});
},
condy::SimpleCQEHandler{});
}

auto fuse_commit_and_fetch_cmd(uint16_t qid, uint64_t commit_id) {
Expand All @@ -211,7 +212,8 @@ auto fuse_commit_and_fetch_cmd(uint16_t qid, uint64_t commit_id) {
*cmd = {};
cmd->qid = qid;
cmd->commit_id = commit_id;
});
},
condy::SimpleCQEHandler{});
}

class FuseServer {
Expand Down
10 changes: 6 additions & 4 deletions examples/ublk-loop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,17 @@ off_t io_desc_offset(size_t q_id) {
}

auto ublk_ctrl_cmd(int fd, int cmd_op, const ublksrv_ctrl_cmd &ctrl) {
return condy::async_uring_cmd(cmd_op, fd, [&](io_uring_sqe *sqe) {
std::memcpy(sqe->cmd, &ctrl, sizeof(ctrl));
});
return condy::async_uring_cmd(
cmd_op, fd,
[&](io_uring_sqe *sqe) { std::memcpy(sqe->cmd, &ctrl, sizeof(ctrl)); },
condy::SimpleCQEHandler{});
}

auto ublk_io_cmd(int cmd_op, const ublksrv_io_cmd &cmd) {
return condy::async_uring_cmd(
cmd_op, condy::fixed(FIXED_FD),
[&](io_uring_sqe *sqe) { std::memcpy(sqe->cmd, &cmd, sizeof(cmd)); });
[&](io_uring_sqe *sqe) { std::memcpy(sqe->cmd, &cmd, sizeof(cmd)); },
condy::SimpleCQEHandler{});
}

condy::Coro<void> setup_device() {
Expand Down
84 changes: 69 additions & 15 deletions include/condy/async_operations.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -696,9 +696,10 @@ inline auto async_recv_multishot(Fd sockfd, ZeroCopyRxBufferPool &pool,
detail::prep_recv_zc_multishot(sqe, sockfd, zcrx_id);
return sqe;
};
auto op = build_multishot_op_awaiter<
SelectBufferCQEHandler<ZeroCopyRxBufferPool>>(
std::move(prep_func), std::forward<MultiShotFunc>(func), &pool);
auto op = build_multishot_op_awaiter(
std::move(prep_func),
SelectBufferCQEHandler<ZeroCopyRxBufferPool>(&pool),
std::forward<MultiShotFunc>(func));
return detail::maybe_flag_fixed_fd(std::move(op), sockfd);
}
#endif
Expand Down Expand Up @@ -870,15 +871,29 @@ inline auto async_socket_direct(int domain, int type, int protocol,

/**
* @brief See io_uring_prep_uring_cmd
* @deprecated Use the overload accepting a CQEHandler instance instead.
* @tparam CQEHandler Custom CQE handler for specific result processing.
* @param cmd_func Function to configure sqe for specific command. Signature:
* void(io_uring_sqe *sqe).
* @param handler_args Arguments forwarded to CQEHandler constructor.
*/
template <CQEHandlerLike CQEHandler = SimpleCQEHandler, FdLike Fd,
typename CmdFunc, typename... Args>
[[deprecated]] inline auto
async_uring_cmd(int cmd_op, Fd fd, CmdFunc &&cmd_func, Args &&...handler_args) {
return async_uring_cmd(cmd_op, fd, std::forward<CmdFunc>(cmd_func),
CQEHandler(std::forward<Args>(handler_args)...));
}

/**
* @brief See io_uring_prep_uring_cmd
* @param cmd_func Function to configure sqe for specific command. Signature:
* void(io_uring_sqe *sqe).
* @param cqe_handler CQE handler for specific result processing.
*/
template <FdLike Fd, typename CmdFunc, CQEHandlerLike CQEHandler>
inline auto async_uring_cmd(int cmd_op, Fd fd, CmdFunc &&cmd_func,
Args &&...handler_args) {
CQEHandler &&cqe_handler) {
auto prep_func = [cmd_op, fd = detail::unwrap_fixed(fd),
cmd_func =
std::forward<CmdFunc>(cmd_func)](detail::Ring *ring) {
Expand All @@ -887,19 +902,43 @@ inline auto async_uring_cmd(int cmd_op, Fd fd, CmdFunc &&cmd_func,
cmd_func(sqe);
return sqe;
};
auto op = build_op_awaiter<CQEHandler>(std::move(prep_func),
std::forward<Args>(handler_args)...);
auto op = build_op_awaiter(std::move(prep_func),
std::forward<CQEHandler>(cqe_handler));
return detail::maybe_flag_fixed_fd(std::move(op), fd);
}

/**
* @copydoc async_uring_cmd
* @brief See io_uring_prep_uring_cmd
* @deprecated Use the overload accepting a CQEHandler instance instead.
* @tparam CQEHandler Custom CQE handler for specific result processing.
* @param cmd_func Function to configure sqe for specific command. Signature:
* void(io_uring_sqe *sqe).
* @param func Callback invoked on each completion except the last one.
* @param handler_args Arguments forwarded to CQEHandler constructor.
*/
template <CQEHandlerLike CQEHandler = SimpleCQEHandler, FdLike Fd,
typename CmdFunc, typename MultiShotFunc, typename... Args>
[[deprecated]] inline auto
async_uring_cmd_multishot(int cmd_op, Fd fd, CmdFunc &&cmd_func,
MultiShotFunc &&func, Args &&...handler_args) {
return async_uring_cmd_multishot(
cmd_op, fd, std::forward<CmdFunc>(cmd_func),
CQEHandler(std::forward<Args>(handler_args)...),
std::forward<MultiShotFunc>(func));
}

/**
* @brief See io_uring_prep_uring_cmd (multi-shot variant)
* @param cmd_func Function to configure sqe for specific command. Signature:
* void(io_uring_sqe *sqe).
* @param cqe_handler CQE handler for specific result processing.
* @param func Callback invoked on each completion except the last one.
*/
template <FdLike Fd, typename CmdFunc, CQEHandlerLike CQEHandler,
typename MultiShotFunc>
inline auto async_uring_cmd_multishot(int cmd_op, Fd fd, CmdFunc &&cmd_func,
MultiShotFunc &&func,
Args &&...handler_args) {
CQEHandler &&cqe_handler,
MultiShotFunc &&func) {
auto prep_func = [cmd_op, fd = detail::unwrap_fixed(fd),
cmd_func =
std::forward<CmdFunc>(cmd_func)](detail::Ring *ring) {
Expand All @@ -908,24 +947,39 @@ inline auto async_uring_cmd_multishot(int cmd_op, Fd fd, CmdFunc &&cmd_func,
cmd_func(sqe);
return sqe;
};
auto op = build_multishot_op_awaiter<CQEHandler>(
std::move(prep_func), std::forward<MultiShotFunc>(func),
std::forward<Args>(handler_args)...);
auto op = build_multishot_op_awaiter(std::move(prep_func),
std::forward<CQEHandler>(cqe_handler),
std::forward<MultiShotFunc>(func));
return detail::maybe_flag_fixed_fd(std::move(op), fd);
}

#if CONDY_URING_VERSION_GE(2, 13) // >= 2.13
/**
* @brief See io_uring_prep_uring_cmd128
* @deprecated Use the overload accepting a CQEHandler instance instead.
* @tparam CQEHandler Custom CQE handler for specific result processing.
* @param cmd_func Function to configure sqe for specific command. Signature:
* void(io_uring_sqe *sqe).
* @param handler_args Arguments forwarded to CQEHandler constructor.
*/
template <CQEHandlerLike CQEHandler = SimpleCQEHandler, FdLike Fd,
typename CmdFunc, typename... Args>
[[deprecated]] inline auto async_uring_cmd128(int cmd_op, Fd fd,
CmdFunc &&cmd_func,
Args &&...handler_args) {
return async_uring_cmd128(cmd_op, fd, std::forward<CmdFunc>(cmd_func),
CQEHandler(std::forward<Args>(handler_args)...));
}

/**
* @brief See io_uring_prep_uring_cmd128
* @param cmd_func Function to configure sqe for specific command. Signature:
* void(io_uring_sqe *sqe).
* @param cqe_handler CQE handler for specific result processing.
*/
template <FdLike Fd, typename CmdFunc, CQEHandlerLike CQEHandler>
inline auto async_uring_cmd128(int cmd_op, Fd fd, CmdFunc &&cmd_func,
Args &&...handler_args) {
CQEHandler &&cqe_handler) {
auto prep_func = [cmd_op, fd = detail::unwrap_fixed(fd),
cmd_func =
std::forward<CmdFunc>(cmd_func)](detail::Ring *ring) {
Expand All @@ -937,8 +991,8 @@ inline auto async_uring_cmd128(int cmd_op, Fd fd, CmdFunc &&cmd_func,
cmd_func(sqe);
return sqe;
};
auto op = build_op_awaiter<CQEHandler>(std::move(prep_func),
std::forward<Args>(handler_args)...);
auto op = build_op_awaiter(std::move(prep_func),
std::forward<CQEHandler>(cqe_handler));
return detail::maybe_flag_fixed_fd(std::move(op), fd);
}
#endif
Expand Down
53 changes: 24 additions & 29 deletions include/condy/awaiter_operations.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,62 +16,57 @@ 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.
* @tparam CQEHandler Type of CQE handler.
* @param func Preparation function that accepts `Ring*` and returns
* `io_uring_sqe*`.
* @param handler_args Arguments forwarded to CQE handler constructor.
* @param cqe_handler CQE handler instance.
* @return OpAwaiter The constructed awaiter.
*/
template <CQEHandlerLike CQEHandler, PrepFuncLike PrepFunc, typename... Args>
auto build_op_awaiter(PrepFunc &&func, Args &&...handler_args) {
return build_op_sender<CQEHandler>(std::forward<PrepFunc>(func),
std::forward<Args>(handler_args)...);
template <PrepFuncLike PrepFunc, CQEHandlerLike CQEHandler>
auto build_op_awaiter(PrepFunc &&func, CQEHandler &&cqe_handler) {
return build_op_sender(std::forward<PrepFunc>(func),
std::forward<CQEHandler>(cqe_handler));
}

/**
* @brief Build a multi-shot operation awaiter with custom CQE handler.
* @tparam CQEHandler Type of CQE handler.
* @tparam PrepFunc Type of preparation function.
* @tparam CQEHandler Type of CQE handler.
* @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 cqe_handler CQE handler instance.
* @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 <CQEHandlerLike CQEHandler, PrepFuncLike PrepFunc,
typename MultiShotFunc, typename... Args>
auto build_multishot_op_awaiter(PrepFunc &&func, MultiShotFunc &&multishot_func,
Args &&...handler_args) {
return build_multishot_op_sender<CQEHandler>(
std::forward<PrepFunc>(func),
std::forward<MultiShotFunc>(multishot_func),
std::forward<Args>(handler_args)...);
template <PrepFuncLike PrepFunc, CQEHandlerLike CQEHandler,
typename MultiShotFunc>
auto build_multishot_op_awaiter(PrepFunc &&func, CQEHandler &&cqe_handler,
MultiShotFunc &&multishot_func) {
return build_multishot_op_sender(
std::forward<PrepFunc>(func), std::forward<CQEHandler>(cqe_handler),
std::forward<MultiShotFunc>(multishot_func));
}

/**
* @brief Build a zero-copy operation awaiter with custom CQE handler.
* @tparam CQEHandler Type of CQE handler.
* @tparam PrepFunc Type of preparation function.
* @tparam CQEHandler Type of CQE handler.
* @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 cqe_handler CQE handler instance.
* @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 <CQEHandlerLike CQEHandler, PrepFuncLike PrepFunc, typename FreeFunc,
typename... Args>
auto build_zero_copy_op_awaiter(PrepFunc &&func, FreeFunc &&free_func,
Args &&...handler_args) {
return build_zero_copy_op_sender<CQEHandler>(
std::forward<PrepFunc>(func), std::forward<FreeFunc>(free_func),
std::forward<Args>(handler_args)...);
template <PrepFuncLike PrepFunc, CQEHandlerLike CQEHandler, typename FreeFunc>
auto build_zero_copy_op_awaiter(PrepFunc &&func, CQEHandler &&cqe_handler,
FreeFunc &&free_func) {
return build_zero_copy_op_sender(std::forward<PrepFunc>(func),
std::forward<CQEHandler>(cqe_handler),
std::forward<FreeFunc>(free_func));
}

} // namespace condy
} // namespace condy
33 changes: 17 additions & 16 deletions include/condy/detail/async_operations.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ auto make_op_awaiter(Func &&func, Args &&...args) {
func(sqe, args...);
return sqe;
};
return build_op_awaiter<SimpleCQEHandler>(std::move(prep_func));
return build_op_awaiter(std::move(prep_func), SimpleCQEHandler{});
}

#if CONDY_URING_VERSION_GE(2, 13) // >= 2.13
Expand All @@ -48,7 +48,7 @@ auto make_op_awaiter128(Func &&func, Args &&...args) {
func(sqe, args...);
return sqe;
};
return build_op_awaiter<SimpleCQEHandler>(std::move(prep_func));
return build_op_awaiter(std::move(prep_func), SimpleCQEHandler{});
}
#endif

Expand All @@ -62,8 +62,9 @@ auto make_multishot_op_awaiter(MultiShotFunc &&multishot_func, Func &&func,
func(sqe, args...);
return sqe;
};
return build_multishot_op_awaiter<SimpleCQEHandler>(
std::move(prep_func), std::forward<MultiShotFunc>(multishot_func));
return build_multishot_op_awaiter(
std::move(prep_func), SimpleCQEHandler{},
std::forward<MultiShotFunc>(multishot_func));
}

template <BufferRingLike Br, typename Func, typename... Args>
Expand All @@ -77,8 +78,8 @@ auto make_select_buffer_op_awaiter(Br *buffers, Func &&func, Args &&...args) {
sqe->buf_group = bgid;
return sqe;
};
return build_op_awaiter<SelectBufferCQEHandler<Br>>(std::move(prep_func),
buffers);
return build_op_awaiter(std::move(prep_func),
SelectBufferCQEHandler<Br>(buffers));
}

template <typename MultiShotFunc, BufferRingLike Br, typename Func,
Expand All @@ -95,9 +96,9 @@ auto make_multishot_select_buffer_op_awaiter(MultiShotFunc &&multishot_func,
sqe->buf_group = bgid;
return sqe;
};
return build_multishot_op_awaiter<SelectBufferCQEHandler<Br>>(
std::move(prep_func), std::forward<MultiShotFunc>(multishot_func),
buffers);
return build_multishot_op_awaiter(
std::move(prep_func), SelectBufferCQEHandler<Br>(buffers),
std::forward<MultiShotFunc>(multishot_func));
}

#if CONDY_URING_VERSION_GE(2, 7) // >= 2.7
Expand All @@ -114,8 +115,8 @@ auto make_bundle_select_buffer_op_awaiter(Br *buffers, Func &&func,
sqe->ioprio |= IORING_RECVSEND_BUNDLE;
return sqe;
};
return build_op_awaiter<SelectBufferCQEHandler<Br>>(std::move(prep_func),
buffers);
return build_op_awaiter(std::move(prep_func),
SelectBufferCQEHandler<Br>(buffers));
}
#endif

Expand All @@ -134,9 +135,9 @@ auto make_multishot_bundle_select_buffer_op_awaiter(
sqe->ioprio |= IORING_RECVSEND_BUNDLE;
return sqe;
};
return build_multishot_op_awaiter<SelectBufferCQEHandler<Br>>(
std::move(prep_func), std::forward<MultiShotFunc>(multishot_func),
buffers);
return build_multishot_op_awaiter(
std::move(prep_func), SelectBufferCQEHandler<Br>(buffers),
std::forward<MultiShotFunc>(multishot_func));
}
#endif

Expand All @@ -150,8 +151,8 @@ auto make_zero_copy_op_awaiter(FreeFunc &&free_func, Func &&func,
func(sqe, args...);
return sqe;
};
return build_zero_copy_op_awaiter<SimpleCQEHandler>(
std::move(prep_func), std::forward<FreeFunc>(free_func));
return build_zero_copy_op_awaiter(std::move(prep_func), SimpleCQEHandler{},
std::forward<FreeFunc>(free_func));
}

template <typename Awaiter>
Expand Down
Loading
Loading