20template <
typename Func,
typename... Args>
21auto make_op_awaiter(Func &&func, Args &&...args) {
22 auto prep_func = [func = std::forward<Func>(func),
23 ... args = std::forward<Args>(args)](Ring *ring) {
24 auto *sqe = ring->get_sqe();
31#if !IO_URING_CHECK_VERSION(2, 13)
32template <
typename Func,
typename... Args>
33auto make_op_awaiter128(Func &&func, Args &&...args) {
34 auto prep_func = [func = std::forward<Func>(func),
35 ... args = std::forward<Args>(args)](Ring *ring) {
36 auto *sqe = ring->get_sqe128();
38 panic_on(
"SQE128 not enabled in the ring");
47template <
typename MultiShotFunc,
typename Func,
typename... Args>
48auto make_multishot_op_awaiter(MultiShotFunc &&multishot_func, Func &&func,
50 auto prep_func = [func = std::forward<Func>(func),
51 ... args = std::forward<Args>(args)](Ring *ring) {
52 auto *sqe = ring->get_sqe();
57 std::move(prep_func), std::forward<MultiShotFunc>(multishot_func));
60template <BufferRingLike Br,
typename Func,
typename... Args>
61auto make_select_buffer_op_awaiter(Br *buffers, Func &&func, Args &&...args) {
62 auto prep_func = [bgid = buffers->bgid(), func = std::forward<Func>(func),
63 ... args = std::forward<Args>(args)](Ring *ring) {
64 auto *sqe = ring->get_sqe();
66 sqe->flags |= IOSQE_BUFFER_SELECT;
67 sqe->buf_group = bgid;
74template <
typename MultiShotFunc, BufferRingLike Br,
typename Func,
76auto make_multishot_select_buffer_op_awaiter(MultiShotFunc &&multishot_func,
77 Br *buffers, Func &&func,
79 auto prep_func = [bgid = buffers->bgid(), func = std::forward<Func>(func),
80 ... args = std::forward<Args>(args)](Ring *ring) {
81 auto *sqe = ring->get_sqe();
83 sqe->flags |= IOSQE_BUFFER_SELECT;
84 sqe->buf_group = bgid;
88 std::move(prep_func), std::forward<MultiShotFunc>(multishot_func),
92#if !IO_URING_CHECK_VERSION(2, 7)
93template <BufferRingLike Br,
typename Func,
typename... Args>
94auto make_bundle_select_buffer_op_awaiter(Br *buffers, Func &&func,
96 auto prep_func = [bgid = buffers->bgid(), func = std::forward<Func>(func),
97 ... args = std::forward<Args>(args)](Ring *ring) {
98 auto *sqe = ring->get_sqe();
100 sqe->flags |= IOSQE_BUFFER_SELECT;
101 sqe->buf_group = bgid;
102 sqe->ioprio |= IORING_RECVSEND_BUNDLE;
110#if !IO_URING_CHECK_VERSION(2, 7)
111template <
typename MultiShotFunc, BufferRingLike Br,
typename Func,
113auto make_multishot_bundle_select_buffer_op_awaiter(
114 MultiShotFunc &&multishot_func, Br *buffers, Func &&func, Args &&...args) {
115 auto prep_func = [bgid = buffers->bgid(), func = std::forward<Func>(func),
116 ... args = std::forward<Args>(args)](Ring *ring) {
117 auto *sqe = ring->get_sqe();
119 sqe->flags |= IOSQE_BUFFER_SELECT;
120 sqe->buf_group = bgid;
121 sqe->ioprio |= IORING_RECVSEND_BUNDLE;
125 std::move(prep_func), std::forward<MultiShotFunc>(multishot_func),
130template <
typename FreeFunc,
typename Func,
typename... Args>
131auto make_zero_copy_op_awaiter(FreeFunc &&free_func, Func &&func,
133 auto prep_func = [func = std::forward<Func>(func),
134 ... args = std::forward<Args>(args)](Ring *ring) {
135 auto *sqe = ring->get_sqe();
140 std::move(prep_func), std::forward<FreeFunc>(free_func));
143template <
typename Awaiter>
144auto maybe_flag_fixed_fd(Awaiter &&op,
const FixedFd &) {
148template <
typename Awaiter>
auto maybe_flag_fixed_fd(Awaiter &&op,
int) {
149 return std::forward<Awaiter>(op);
152template <
typename Fd>
153constexpr bool is_fixed_fd_v = std::is_same_v<std::remove_cvref_t<Fd>, FixedFd>;
155inline void prep_sendto(io_uring_sqe *sqe,
int sockfd,
const void *buf,
156 size_t len,
int flags,
const struct sockaddr *addr,
157 socklen_t addrlen)
noexcept {
158 io_uring_prep_send(sqe, sockfd, buf, len, flags);
159 io_uring_prep_send_set_addr(sqe, addr, addrlen);
162inline void prep_send_fixed(io_uring_sqe *sqe,
int sockfd,
const void *buf,
163 size_t len,
int flags,
int buf_index)
noexcept {
164 io_uring_prep_send(sqe, sockfd, buf, len, flags);
165 sqe->ioprio |= IORING_RECVSEND_FIXED_BUF;
166 sqe->buf_index = buf_index;
169inline void prep_sendto_fixed(io_uring_sqe *sqe,
int sockfd,
const void *buf,
170 size_t len,
int flags,
171 const struct sockaddr *addr, socklen_t addrlen,
172 int buf_index)
noexcept {
173 prep_sendto(sqe, sockfd, buf, len, flags, addr, addrlen);
174 sqe->ioprio |= IORING_RECVSEND_FIXED_BUF;
175 sqe->buf_index = buf_index;
178inline void prep_sendto_zc(io_uring_sqe *sqe,
int sockfd,
const void *buf,
179 size_t len,
int flags,
const struct sockaddr *addr,
180 socklen_t addrlen,
unsigned zc_flags)
noexcept {
181 io_uring_prep_send_zc(sqe, sockfd, buf, len, flags, zc_flags);
182 io_uring_prep_send_set_addr(sqe, addr, addrlen);
185inline void prep_sendto_zc_fixed(io_uring_sqe *sqe,
int sockfd,
const void *buf,
186 size_t len,
int flags,
187 const struct sockaddr *addr, socklen_t addrlen,
188 unsigned zc_flags,
int buf_index)
noexcept {
189 prep_sendto_zc(sqe, sockfd, buf, len, flags, addr, addrlen, zc_flags);
190 sqe->ioprio |= IORING_RECVSEND_FIXED_BUF;
191 sqe->buf_index = buf_index;
194#if !IO_URING_CHECK_VERSION(2, 15)
195inline void prep_recv_zc_multishot(io_uring_sqe *sqe,
int fd,
197 io_uring_prep_rw(IORING_OP_RECV_ZC, sqe, fd,
nullptr, 0, 0);
198 sqe->ioprio |= IORING_RECV_MULTISHOT;
199 sqe->zcrx_ifq_idx = zcrx_id;
Helper functions for composing asynchronous operations.
Definitions of CQE handlers.
Helper functions for asynchronous operations.
The main namespace for the Condy library.
auto build_op_awaiter(PrepFunc &&func, Args &&...handler_args)
Build a single-shot operation awaiter with custom CQE handler.
auto build_zero_copy_op_awaiter(PrepFunc &&func, FreeFunc &&free_func, Args &&...handler_args)
Build a zero-copy operation awaiter with custom CQE handler.
auto build_multishot_op_awaiter(PrepFunc &&func, MultiShotFunc &&multishot_func, Args &&...handler_args)
Build a multi-shot operation awaiter with custom CQE handler.
auto flag(Sender &&sender)
Decorates an operation with specific io_uring sqe flags.