Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
7e38038
move HandleBox to finish_handles.hpp
wokron Apr 7, 2026
524917a
add op sender
wokron Apr 7, 2026
6ecda8c
add when_all
wokron Apr 7, 2026
2aec192
add link and hard_link
wokron Apr 7, 2026
7b84475
add flag
wokron Apr 7, 2026
7e1cf37
add parallel
wokron Apr 7, 2026
45260ed
add std::stop_token
wokron Apr 7, 2026
191c6ec
add when_any
wokron Apr 7, 2026
89fffe4
extract Canceller
wokron Apr 7, 2026
3ec2683
extract ParallelOperationState
wokron Apr 7, 2026
8c58240
extract Parallel{Any,All}OperationState
wokron Apr 7, 2026
0c79225
change when_any return value
wokron Apr 7, 2026
dab0276
add parallel any/all test
wokron Apr 7, 2026
17ff62b
add && and ||
wokron Apr 7, 2026
c11dfee
add >>
wokron Apr 7, 2026
879f79f
support empty parallel
wokron Apr 7, 2026
8c25204
extract tuple_at to utils
wokron Apr 8, 2026
1ace9eb
remove useless start()
wokron Apr 8, 2026
93466a4
support ranged parallel sender
wokron Apr 8, 2026
ccedd63
add ranged link
wokron Apr 8, 2026
73a4b3b
await_transform for sender
wokron Apr 8, 2026
6a36233
add make_*_sender api
wokron Apr 9, 2026
3368962
add Channel senders
wokron Apr 10, 2026
84ca003
add channel sender cancel
wokron Apr 10, 2026
7b4ff79
fix sender build
wokron Apr 10, 2026
50949ed
use sender
wokron Apr 10, 2026
9e5f84c
fix sender stop
wokron Apr 10, 2026
5f4f725
update unit tests
wokron Apr 10, 2026
d33985c
remove uesless parallel finish handle
wokron Apr 10, 2026
caa1ac2
format all
wokron Apr 10, 2026
8d2b513
remove useless detail function
wokron Apr 11, 2026
7109cfe
simplify ReceiverWrapper
wokron Apr 11, 2026
4672daf
channel remove useless method
wokron Apr 11, 2026
c2e5514
refactor HandleBox
wokron Apr 11, 2026
e49430d
update headers
wokron Apr 11, 2026
01b5474
add maybe_reset()
wokron Apr 11, 2026
221aa8d
OpFinishHandle accept receiver
wokron Apr 11, 2026
05d8c1d
extract finish_
wokron Apr 11, 2026
e417060
ensure OpFinishHandle has fixed addr
wokron Apr 11, 2026
168b81f
update ring test
wokron Apr 11, 2026
7d671e9
update op_finish_handle test
wokron Apr 11, 2026
f640516
move size check position
wokron Apr 11, 2026
ceca80d
inline channel completion
wokron Apr 12, 2026
ccb5d78
simplify channel cancel
wokron Apr 12, 2026
2c20dc8
refactor channel PopFinishHandle
wokron Apr 12, 2026
d5b30de
refactor channel PushFinishHandle
wokron Apr 12, 2026
b9471d8
support immediate resume
wokron Apr 12, 2026
04b7fa3
optim SenderAwaiter
wokron Apr 13, 2026
743b6b3
finish todo in channel
wokron Apr 13, 2026
b26a118
rename to maybe_set_cancel()
wokron Apr 13, 2026
8c407f3
op_state misc updates
wokron Apr 13, 2026
afedd50
add missing headers
wokron Apr 14, 2026
1e9f451
update channel docs
wokron Apr 14, 2026
e692cd9
minor fix
wokron Apr 15, 2026
92307b2
minor fix
wokron Apr 16, 2026
d69b765
remove useless concepts
wokron Apr 16, 2026
ab3ca6a
simplify tuple_at
wokron Apr 17, 2026
845b03f
add comments for sender operation
wokron Apr 18, 2026
83a9636
add file comments
wokron Apr 18, 2026
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
4 changes: 2 additions & 2 deletions include/condy/async_operations.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ namespace detail {
class BundledProvidedBufferQueue;
class BundledProvidedBufferPool;

template <AwaiterLike Awaiter>
template <typename Awaiter>
auto maybe_flag_fixed_fd(Awaiter &&op, const FixedFd &) {
return flag<IOSQE_FIXED_FILE>(std::forward<Awaiter>(op));
}

template <AwaiterLike Awaiter> auto maybe_flag_fixed_fd(Awaiter &&op, int) {
template <typename Awaiter> auto maybe_flag_fixed_fd(Awaiter &&op, int) {
return std::forward<Awaiter>(op);
}

Expand Down
221 changes: 5 additions & 216 deletions include/condy/awaiter_operations.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@

#pragma once

#include "condy/awaiters.hpp"
#include "condy/concepts.hpp"
#include "condy/cqe_handler.hpp"
#include "condy/ring.hpp"
#include "condy/sender_operations.hpp"

namespace condy {

Expand All @@ -28,8 +28,8 @@ namespace condy {
*/
template <CQEHandlerLike CQEHandler, PrepFuncLike PrepFunc, typename... Args>
auto build_op_awaiter(PrepFunc &&func, Args &&...handler_args) {
return OpAwaiter<std::decay_t<PrepFunc>, CQEHandler>(
std::forward<PrepFunc>(func), std::forward<Args>(handler_args)...);
return build_op_sender<CQEHandler>(std::forward<PrepFunc>(func),
std::forward<Args>(handler_args)...);
}

/**
Expand All @@ -49,8 +49,7 @@ template <CQEHandlerLike CQEHandler, PrepFuncLike PrepFunc,
typename MultiShotFunc, typename... Args>
auto build_multishot_op_awaiter(PrepFunc &&func, MultiShotFunc &&multishot_func,
Args &&...handler_args) {
return MultiShotOpAwaiter<std::decay_t<PrepFunc>, CQEHandler,
std::decay_t<MultiShotFunc>>(
return build_multishot_op_sender<CQEHandler>(
std::forward<PrepFunc>(func),
std::forward<MultiShotFunc>(multishot_func),
std::forward<Args>(handler_args)...);
Expand All @@ -72,8 +71,7 @@ template <CQEHandlerLike CQEHandler, PrepFuncLike PrepFunc, typename FreeFunc,
typename... Args>
auto build_zero_copy_op_awaiter(PrepFunc &&func, FreeFunc &&free_func,
Args &&...handler_args) {
return ZeroCopyOpAwaiter<std::decay_t<PrepFunc>, CQEHandler,
std::decay_t<FreeFunc>>(
return build_zero_copy_op_sender<CQEHandler>(
std::forward<PrepFunc>(func), std::forward<FreeFunc>(free_func),
std::forward<Args>(handler_args)...);
}
Expand Down Expand Up @@ -205,213 +203,4 @@ auto make_zero_copy_op_awaiter(FreeFunc &&free_func, Func &&func,

} // namespace detail

/**
* @brief Decorates an awaiter with specific io_uring sqe flags.
* @tparam Flags The io_uring sqe flags to set.
* @param awaiter The awaiter to decorate.
* @return auto The decorated awaiter.
*/
template <unsigned int Flags, AwaiterLike Awaiter>
auto flag(Awaiter &&awaiter) {
return FlaggedOpAwaiter<Flags, std::decay_t<Awaiter>>(
std::forward<Awaiter>(awaiter));
}

/**
* @brief Mark an awaiter as drain operation.
* @param awaiter The awaiter to decorate.
*/
template <AwaiterLike Awaiter> auto drain(Awaiter &&awaiter) {
return flag<IOSQE_IO_DRAIN>(std::forward<Awaiter>(awaiter));
}

/**
* @brief Mark an awaiter to always execute asynchronously.
* @param awaiter The awaiter to decorate.
*/
template <AwaiterLike Awaiter> auto always_async(Awaiter &&awaiter) {
return flag<IOSQE_ASYNC>(std::forward<Awaiter>(awaiter));
}

/**
* @brief Compose multiple awaiters into a single awaiter that executes them in
* parallel.
* @tparam AwaiterType Awaiter template to use for composing the awaiters.
* @tparam Awaiter Types of the awaiters to compose.
* @param awaiters The awaiters to compose.
* @return auto The composed awaiter.
*/
template <template <AwaiterLike... Awaiter> typename AwaiterType,
AwaiterLike... Awaiter>
auto parallel(Awaiter &&...awaiters) {
return AwaiterType<std::decay_t<Awaiter>...>(
std::forward<Awaiter>(awaiters)...);
}

/**
* @brief Compose multiple awaiters from a range into a single awaiter that
* executes them in parallel.
* @tparam RangedAwaiterType Awaiter template to use for composing the awaiters.
* @tparam Range Type of the range containing the awaiters.
* @param range The range of awaiters to compose.
* @return auto The composed awaiter.
*/
template <template <typename Awaiter> typename RangedAwaiterType,
AwaiterRange Range>
auto parallel(Range &&range) {
using AwaiterType = typename std::decay_t<Range>::value_type;
auto begin = std::make_move_iterator(std::begin(range));
auto end = std::make_move_iterator(std::end(range));
std::vector<AwaiterType> awaiters(begin, end);
return RangedAwaiterType<AwaiterType>(std::move(awaiters));
}

/**
* @brief Compose multiple awaiters into a single awaiter that completes when
* all of them complete.
* @tparam Awaiters Types of the awaiters to compose.
* @param awaiters The awaiters to compose.
* @return WhenAllAwaiter The composed awaiter.
*/
template <AwaiterLike... Awaiters> auto when_all(Awaiters &&...awaiters) {
return parallel<WhenAllAwaiter>(std::forward<Awaiters>(awaiters)...);
}

/**
* @brief Compose multiple awaiters from a range into a single awaiter that
* completes when all of them complete.
* @tparam Range Type of the range containing the awaiters.
* @param range The range of awaiters to compose.
* @return RangedWhenAllAwaiter The composed awaiter.
*/
template <AwaiterRange Range> auto when_all(Range &&range) {
return parallel<RangedWhenAllAwaiter>(std::forward<Range>(range));
}

/**
* @brief Compose multiple awaiters into a single awaiter that completes when
* any of them complete.
* @tparam Awaiters Types of the awaiters to compose.
* @param awaiters The awaiters to compose.
* @return WhenAnyAwaiter The composed awaiter.
* @note If multiple awaiters complete simultaneously, the result will only
* contain one of the results.
*/
template <AwaiterLike... Awaiters> auto when_any(Awaiters &&...awaiters) {
return parallel<WhenAnyAwaiter>(std::forward<Awaiters>(awaiters)...);
}

/**
* @brief Compose multiple awaiters from a range into a single awaiter that
* completes when any of them complete.
* @tparam Range Type of the range containing the awaiters.
* @param range The range of awaiters to compose.
* @return RangedWhenAnyAwaiter The composed awaiter.
*/
template <AwaiterRange Range> auto when_any(Range &&range) {
return parallel<RangedWhenAnyAwaiter>(std::forward<Range>(range));
}

/**
* @brief Compose multiple awaiters into a single awaiter that executes them in
* sequence.
* @tparam Awaiters Types of the awaiters to compose.
* @param awaiters The awaiters to compose.
* @return LinkAwaiter The composed awaiter.
*/
template <AwaiterLike... Awaiters> auto link(Awaiters &&...awaiters) {
return parallel<LinkAwaiter>(std::forward<Awaiters>(awaiters)...);
}

/**
* @brief Compose multiple awaiters from a range into a single awaiter that
* executes them in sequence.
* @tparam Range Type of the range containing the awaiters.
* @param range The range of awaiters to compose.
* @return RangedLinkAwaiter The composed awaiter.
*/
template <AwaiterRange Range> auto link(Range &&range) {
return parallel<RangedLinkAwaiter>(std::forward<Range>(range));
}

/**
* @brief Compose multiple awaiters into a single awaiter that executes them in
* sequence and continues even if one of them fails.
* @tparam Awaiters Types of the awaiters to compose.
* @param awaiters The awaiters to compose.
* @return HardLinkAwaiter The composed awaiter.
*/
template <AwaiterLike... Awaiters> auto hard_link(Awaiters &&...awaiters) {
return parallel<HardLinkAwaiter>(std::forward<Awaiters>(awaiters)...);
}

/**
* @brief Compose multiple awaiters from a range into a single awaiter that
* executes them in sequence and continues even if one of them fails.
* @tparam Range Type of the range containing the awaiters.
* @param range The range of awaiters to compose.
* @return RangedHardLinkAwaiter The composed awaiter.
*/
template <AwaiterRange Range> auto hard_link(Range &&range) {
return parallel<RangedHardLinkAwaiter>(std::forward<Range>(range));
}

/**
* @brief Operators for composing awaiters.
*/
namespace operators {

/**
* @brief Operator overloads version of when_all
*/
template <AwaiterLike Awaiter1, AwaiterLike Awaiter2>
auto operator&&(Awaiter1 aw1, Awaiter2 aw2) {
return when_all(std::move(aw1), std::move(aw2));
}

/**
* @brief Operator overloads version of when_all
*/
template <AwaiterLike Awaiter, AwaiterLike... Awaiters>
auto operator&&(WhenAllAwaiter<Awaiters...> aws, Awaiter aw) {
return WhenAllAwaiter<Awaiters..., std::decay_t<Awaiter>>(std::move(aws),
std::move(aw));
}

/**
* @brief Operator overloads version of when_any
*/
template <AwaiterLike Awaiter1, AwaiterLike Awaiter2>
auto operator||(Awaiter1 aw1, Awaiter2 aw2) {
return when_any(std::move(aw1), std::move(aw2));
}

/**
* @brief Operator overloads version of when_any
*/
template <AwaiterLike Awaiter, AwaiterLike... Awaiters>
auto operator||(WhenAnyAwaiter<Awaiters...> aws, Awaiter aw) {
return WhenAnyAwaiter<Awaiters..., std::decay_t<Awaiter>>(std::move(aws),
std::move(aw));
}

/**
* @brief Operator overloads version of link
*/
template <AwaiterLike Awaiter1, AwaiterLike Awaiter2>
auto operator>>(Awaiter1 aw1, Awaiter2 aw2) {
return link(std::move(aw1), std::move(aw2));
}

/**
* @brief Operator overloads version of link
*/
template <AwaiterLike Awaiter, AwaiterLike... Awaiters>
auto operator>>(LinkAwaiter<Awaiters...> aws, Awaiter aw) {
return LinkAwaiter<Awaiters..., std::decay_t<Awaiter>>(std::move(aws),
std::move(aw));
}

} // namespace operators

} // namespace condy
Loading
Loading