Condy v1.1.0
C++ Asynchronous System Call Layer for Linux
Loading...
Searching...
No Matches
awaiter_operations.hpp
Go to the documentation of this file.
1
9
10#pragma once
11
12#include "condy/awaiters.hpp"
13#include "condy/concepts.hpp"
14
15namespace condy {
16
22template <typename Func, typename... Args>
23auto make_op_awaiter(Func &&func, Args &&...args) {
24 auto prep_func = [func = std::forward<Func>(func),
25 ... args = std::forward<Args>(args)](auto sqe) {
26 func(sqe, args...);
27 };
28 return OpAwaiter<decltype(prep_func)>(std::move(prep_func));
29}
30
34template <typename MultiShotFunc, typename Func, typename... Args>
35auto make_multishot_op_awaiter(MultiShotFunc &&multishot_func, Func &&func,
36 Args &&...args) {
37 auto prep_func = [func = std::forward<Func>(func),
38 ... args = std::forward<Args>(args)](auto sqe) {
39 func(sqe, args...);
40 };
41 return MultiShotOpAwaiter<std::decay_t<MultiShotFunc>, decltype(prep_func)>(
42 std::forward<MultiShotFunc>(multishot_func), std::move(prep_func));
43}
44
48template <BufferRingLike Br, typename Func, typename... Args>
49auto make_select_buffer_op_awaiter(Br *buffers, Func &&func, Args &&...args) {
50 auto prep_func = [bgid = buffers->bgid(), func = std::forward<Func>(func),
51 ... args = std::forward<Args>(args)](auto sqe) {
52 func(sqe, args...);
53 sqe->flags |= IOSQE_BUFFER_SELECT;
54 sqe->buf_group = bgid;
55 };
56 auto op = SelectBufferOpAwaiter<Br, decltype(prep_func)>(
57 buffers, std::move(prep_func));
58 return op;
59}
60
64template <typename MultiShotFunc, BufferRingLike Br, typename Func,
65 typename... Args>
66auto make_multishot_select_buffer_op_awaiter(MultiShotFunc &&multishot_func,
67 Br *buffers, Func &&func,
68 Args &&...args) {
69 auto prep_func = [bgid = buffers->bgid(), func = std::forward<Func>(func),
70 ... args = std::forward<Args>(args)](auto sqe) {
71 func(sqe, args...);
72 sqe->flags |= IOSQE_BUFFER_SELECT;
73 sqe->buf_group = bgid;
74 };
75 auto op = MultiShotSelectBufferOpAwaiter<std::decay_t<MultiShotFunc>, Br,
76 decltype(prep_func)>(
77 std::forward<MultiShotFunc>(multishot_func), buffers,
78 std::move(prep_func));
79 return op;
80}
81
82#if !IO_URING_CHECK_VERSION(2, 7) // >= 2.7
86template <BufferRingLike Br, typename Func, typename... Args>
87auto make_bundle_select_buffer_op_awaiter(Br *buffers, Func &&func,
88 Args &&...args) {
89 auto prep_func = [bgid = buffers->bgid(), func = std::forward<Func>(func),
90 ... args = std::forward<Args>(args)](auto sqe) {
91 func(sqe, args...);
92 sqe->flags |= IOSQE_BUFFER_SELECT;
93 sqe->buf_group = bgid;
94 sqe->ioprio |= IORING_RECVSEND_BUNDLE;
95 };
96 auto op = SelectBufferOpAwaiter<Br, decltype(prep_func)>(
97 buffers, std::move(prep_func));
98 return op;
99}
100#endif
101
102#if !IO_URING_CHECK_VERSION(2, 7) // >= 2.7
106template <typename MultiShotFunc, BufferRingLike Br, typename Func,
107 typename... Args>
109 MultiShotFunc &&multishot_func, Br *buffers, Func &&func, Args &&...args) {
110 auto prep_func = [bgid = buffers->bgid(), func = std::forward<Func>(func),
111 ... args = std::forward<Args>(args)](auto sqe) {
112 func(sqe, args...);
113 sqe->flags |= IOSQE_BUFFER_SELECT;
114 sqe->buf_group = bgid;
115 sqe->ioprio |= IORING_RECVSEND_BUNDLE;
116 };
117 auto op = MultiShotSelectBufferOpAwaiter<std::decay_t<MultiShotFunc>, Br,
118 decltype(prep_func)>(
119 std::forward<MultiShotFunc>(multishot_func), buffers,
120 std::move(prep_func));
121 return op;
122}
123#endif
124
128template <typename FreeFunc, typename Func, typename... Args>
129auto make_zero_copy_op_awaiter(FreeFunc &&free_func, Func &&func,
130 Args &&...args) {
131 auto prep_func = [func = std::forward<Func>(func),
132 ... args = std::forward<Args>(args)](auto sqe) {
133 func(sqe, args...);
134 };
135 return ZeroCopyOpAwaiter<std::decay_t<FreeFunc>, decltype(prep_func)>(
136 std::forward<FreeFunc>(free_func), std::move(prep_func));
137}
138
145template <unsigned int Flags, AwaiterLike Awaiter>
146auto flag(Awaiter &&awaiter) {
147 return FlaggedOpAwaiter<Flags, std::decay_t<Awaiter>>(
148 std::forward<Awaiter>(awaiter));
149}
150
155template <AwaiterLike Awaiter> auto drain(Awaiter &&awaiter) {
156 return flag<IOSQE_IO_DRAIN>(std::forward<Awaiter>(awaiter));
157}
158
163template <AwaiterLike Awaiter> auto always_async(Awaiter &&awaiter) {
164 return flag<IOSQE_ASYNC>(std::forward<Awaiter>(awaiter));
165}
166
175template <template <AwaiterLike... Awaiter> typename AwaiterType,
176 AwaiterLike... Awaiter>
177auto parallel(Awaiter &&...awaiters) {
178 return AwaiterType<std::decay_t<Awaiter>...>(
179 std::forward<Awaiter>(awaiters)...);
180}
181
190template <template <typename Awaiter> typename RangedAwaiterType,
191 AwaiterRange Range>
192auto parallel(Range &&range) {
193 using AwaiterType = typename std::decay_t<Range>::value_type;
194 auto begin = std::make_move_iterator(std::begin(range));
195 auto end = std::make_move_iterator(std::end(range));
196 std::vector<AwaiterType> awaiters(begin, end);
197 return RangedAwaiterType<AwaiterType>(std::move(awaiters));
198}
199
207template <AwaiterLike... Awaiters> auto when_all(Awaiters &&...awaiters) {
208 return parallel<WhenAllAwaiter>(std::forward<Awaiters>(awaiters)...);
209}
210
218template <AwaiterRange Range> auto when_all(Range &&range) {
219 return parallel<RangedWhenAllAwaiter>(std::forward<Range>(range));
220}
221
231template <AwaiterLike... Awaiters> auto when_any(Awaiters &&...awaiters) {
232 return parallel<WhenAnyAwaiter>(std::forward<Awaiters>(awaiters)...);
233}
234
242template <AwaiterRange Range> auto when_any(Range &&range) {
243 return parallel<RangedWhenAnyAwaiter>(std::forward<Range>(range));
244}
245
253template <AwaiterLike... Awaiters> auto link(Awaiters &&...awaiters) {
254 return parallel<LinkAwaiter>(std::forward<Awaiters>(awaiters)...);
255}
256
264template <AwaiterRange Range> auto link(Range &&range) {
265 return parallel<RangedLinkAwaiter>(std::forward<Range>(range));
266}
267
275template <AwaiterLike... Awaiters> auto hard_link(Awaiters &&...awaiters) {
276 return parallel<HardLinkAwaiter>(std::forward<Awaiters>(awaiters)...);
277}
278
286template <AwaiterRange Range> auto hard_link(Range &&range) {
287 return parallel<RangedHardLinkAwaiter>(std::forward<Range>(range));
288}
289
293namespace operators {
294
298template <AwaiterLike Awaiter1, AwaiterLike Awaiter2>
299auto operator&&(Awaiter1 aw1, Awaiter2 aw2) {
300 return when_all(std::move(aw1), std::move(aw2));
301}
302
306template <AwaiterLike Awaiter, AwaiterLike... Awaiters>
308 return WhenAllAwaiter<Awaiters..., std::decay_t<Awaiter>>(std::move(aws),
309 std::move(aw));
310}
311
315template <AwaiterLike Awaiter1, AwaiterLike Awaiter2>
316auto operator||(Awaiter1 aw1, Awaiter2 aw2) {
317 return when_any(std::move(aw1), std::move(aw2));
318}
319
323template <AwaiterLike Awaiter, AwaiterLike... Awaiters>
325 return WhenAnyAwaiter<Awaiters..., std::decay_t<Awaiter>>(std::move(aws),
326 std::move(aw));
327}
328
332template <AwaiterLike Awaiter1, AwaiterLike Awaiter2>
333auto operator>>(Awaiter1 aw1, Awaiter2 aw2) {
334 return link(std::move(aw1), std::move(aw2));
335}
336
340template <AwaiterLike Awaiter, AwaiterLike... Awaiters>
342 return LinkAwaiter<Awaiters..., std::decay_t<Awaiter>>(std::move(aws),
343 std::move(aw));
344}
345
346} // namespace operators
347
348} // namespace condy
Definitions of awaiter types for asynchronous operations.
Operators for composing awaiters.
Definition awaiter_operations.hpp:293
auto operator||(Awaiter1 aw1, Awaiter2 aw2)
Operator overloads version of when_any.
Definition awaiter_operations.hpp:316
auto operator&&(Awaiter1 aw1, Awaiter2 aw2)
Operator overloads version of when_all.
Definition awaiter_operations.hpp:299
auto operator>>(Awaiter1 aw1, Awaiter2 aw2)
Operator overloads version of link.
Definition awaiter_operations.hpp:333
The main namespace for the Condy library.
Definition condy.hpp:28
auto make_multishot_select_buffer_op_awaiter(MultiShotFunc &&multishot_func, Br *buffers, Func &&func, Args &&...args)
This function creates a variant of OpAwaiter. OpAwaiter represents an asynchronous operation that can...
Definition awaiter_operations.hpp:66
auto make_op_awaiter(Func &&func, Args &&...args)
This function creates a variant of OpAwaiter. OpAwaiter represents an asynchronous operation that can...
Definition awaiter_operations.hpp:23
auto parallel(Awaiter &&...awaiters)
Compose multiple awaiters into a single awaiter that executes them in parallel.
Definition awaiter_operations.hpp:177
auto make_bundle_select_buffer_op_awaiter(Br *buffers, Func &&func, Args &&...args)
This function creates a variant of OpAwaiter. OpAwaiter represents an asynchronous operation that can...
Definition awaiter_operations.hpp:87
auto drain(Awaiter &&awaiter)
Mark an awaiter as drain operation.
Definition awaiter_operations.hpp:155
auto when_all(Awaiters &&...awaiters)
Compose multiple awaiters into a single awaiter that completes when all of them complete.
Definition awaiter_operations.hpp:207
auto make_multishot_op_awaiter(MultiShotFunc &&multishot_func, Func &&func, Args &&...args)
This function creates a variant of OpAwaiter. OpAwaiter represents an asynchronous operation that can...
Definition awaiter_operations.hpp:35
auto make_zero_copy_op_awaiter(FreeFunc &&free_func, Func &&func, Args &&...args)
This function creates a variant of OpAwaiter. OpAwaiter represents an asynchronous operation that can...
Definition awaiter_operations.hpp:129
auto link(Awaiters &&...awaiters)
Compose multiple awaiters into a single awaiter that executes them in sequence.
Definition awaiter_operations.hpp:253
auto make_select_buffer_op_awaiter(Br *buffers, Func &&func, Args &&...args)
This function creates a variant of OpAwaiter. OpAwaiter represents an asynchronous operation that can...
Definition awaiter_operations.hpp:49
LinkAwaiterBase< IOSQE_IO_LINK, Awaiter... > LinkAwaiter
Awaiter that links multiple operations using IO_LINK.
Definition awaiters.hpp:487
auto when_any(Awaiters &&...awaiters)
Compose multiple awaiters into a single awaiter that completes when any of them complete.
Definition awaiter_operations.hpp:231
auto flag(Awaiter &&awaiter)
Decorates an awaiter with specific io_uring sqe flags.
Definition awaiter_operations.hpp:146
ParallelAwaiterBase< WhenAllFinishHandle< typename Awaiter::HandleType... >, Awaiter... > WhenAllAwaiter
Awaiter that waits for all operations to complete in parallel.
Definition awaiters.hpp:433
auto hard_link(Awaiters &&...awaiters)
Compose multiple awaiters into a single awaiter that executes them in sequence and continues even if ...
Definition awaiter_operations.hpp:275
ParallelAwaiterBase< WhenAnyFinishHandle< typename Awaiter::HandleType... >, Awaiter... > WhenAnyAwaiter
Awaiter that waits for any operation to complete in parallel.
Definition awaiters.hpp:445
auto make_multishot_bundle_select_buffer_op_awaiter(MultiShotFunc &&multishot_func, Br *buffers, Func &&func, Args &&...args)
This function creates a variant of OpAwaiter. OpAwaiter represents an asynchronous operation that can...
Definition awaiter_operations.hpp:108
auto always_async(Awaiter &&awaiter)
Mark an awaiter to always execute asynchronously.
Definition awaiter_operations.hpp:163