Condy v1.1.0
C++ Asynchronous System Call Layer for Linux
Loading...
Searching...
No Matches
async_operations.hpp
Go to the documentation of this file.
1
8
9#pragma once
10
12#include "condy/concepts.hpp"
13#include "condy/condy_uring.hpp"
14#include "condy/helpers.hpp"
16
17namespace condy {
18
19namespace detail {
20
21template <AwaiterLike Awaiter>
22auto maybe_flag_fixed_fd(Awaiter &&op, const FixedFd &) {
23 return flag<IOSQE_FIXED_FILE>(std::forward<Awaiter>(op));
24}
25
26template <AwaiterLike Awaiter> auto maybe_flag_fixed_fd(Awaiter &&op, int) {
27 return std::forward<Awaiter>(op);
28}
29
30template <typename Fd>
31constexpr bool is_fixed_fd_v = std::is_same_v<std::decay_t<Fd>, FixedFd>;
32
33} // namespace detail
34
38template <FdLike Fd1, FdLike Fd2>
39inline auto async_splice(Fd1 fd_in, int64_t off_in, Fd2 fd_out, int64_t off_out,
40 unsigned int nbytes, unsigned int splice_flags) {
41 if constexpr (detail::is_fixed_fd_v<Fd1>) {
42 splice_flags |= SPLICE_F_FD_IN_FIXED;
43 }
44 auto op = make_op_awaiter(io_uring_prep_splice, fd_in, off_in, fd_out,
45 off_out, nbytes, splice_flags);
46 return detail::maybe_flag_fixed_fd(std::move(op), fd_out);
47}
48
52template <FdLike Fd1, FdLike Fd2>
53inline auto async_tee(Fd1 fd_in, Fd2 fd_out, unsigned int nbytes,
54 unsigned int splice_flags) {
55 if constexpr (detail::is_fixed_fd_v<Fd1>) {
56 splice_flags |= SPLICE_F_FD_IN_FIXED;
57 }
58 auto op =
59 make_op_awaiter(io_uring_prep_tee, fd_in, fd_out, nbytes, splice_flags);
60 return detail::maybe_flag_fixed_fd(std::move(op), fd_out);
61}
62
66template <FdLike Fd>
67inline auto async_readv(Fd fd, const struct iovec *iovecs, unsigned nr_vecs,
68 __u64 offset, int flags) {
69 auto op = make_op_awaiter(io_uring_prep_readv2, fd, iovecs, nr_vecs, offset,
70 flags);
71 return detail::maybe_flag_fixed_fd(std::move(op), fd);
72}
73
74#if !IO_URING_CHECK_VERSION(2, 10) // >= 2.10
78template <FdLike Fd>
79inline auto async_readv(Fd fd, detail::FixedBuffer<const iovec *> iovecs,
80 unsigned nr_vecs, __u64 offset, int flags) {
81 auto op = make_op_awaiter(io_uring_prep_readv_fixed, fd, iovecs.value,
82 nr_vecs, offset, flags, iovecs.buf_index);
83 return detail::maybe_flag_fixed_fd(std::move(op), fd);
84}
85#endif
86
87template <FdLike Fd>
91inline auto async_writev(Fd fd, const struct iovec *iovecs,
92 unsigned int nr_vecs, __u64 offset, int flags) {
93 auto op = make_op_awaiter(io_uring_prep_writev2, fd, iovecs, nr_vecs,
94 offset, flags);
95 return detail::maybe_flag_fixed_fd(std::move(op), fd);
96}
97
98#if !IO_URING_CHECK_VERSION(2, 10) // >= 2.10
102template <FdLike Fd>
103inline auto async_writev(Fd fd, detail::FixedBuffer<const iovec *> iovecs,
104 unsigned int nr_vecs, __u64 offset, int flags) {
105 auto op = make_op_awaiter(io_uring_prep_writev_fixed, fd, iovecs.value,
106 nr_vecs, offset, flags, iovecs.buf_index);
107 return detail::maybe_flag_fixed_fd(std::move(op), fd);
108}
109#endif
110
114template <FdLike Fd>
115inline auto async_recvmsg(Fd fd, struct msghdr *msg, unsigned flags) {
116 auto op = make_op_awaiter(io_uring_prep_recvmsg, fd, msg, flags);
117 return detail::maybe_flag_fixed_fd(std::move(op), fd);
118}
119
123template <FdLike Fd, typename MultiShotFunc, NotBundledBufferRing Buffer>
124inline auto async_recvmsg_multishot(Fd fd, struct msghdr *msg, unsigned flags,
125 Buffer &buf, MultiShotFunc &&func) {
127 std::forward<MultiShotFunc>(func), &buf,
128 io_uring_prep_recvmsg_multishot, fd, msg, flags);
129 return detail::maybe_flag_fixed_fd(std::move(op), fd);
130}
131
135template <FdLike Fd>
136inline auto async_sendmsg(Fd fd, const struct msghdr *msg, unsigned flags) {
137 auto op = make_op_awaiter(io_uring_prep_sendmsg, fd, msg, flags);
138 return detail::maybe_flag_fixed_fd(std::move(op), fd);
139}
140
144template <FdLike Fd, typename FreeFunc>
145inline auto async_sendmsg_zc(Fd fd, const struct msghdr *msg, unsigned flags,
146 FreeFunc &&func) {
148 std::forward<FreeFunc>(func), io_uring_prep_sendmsg_zc, fd, msg, flags);
149 return detail::maybe_flag_fixed_fd(std::move(op), fd);
150}
151
152#if !IO_URING_CHECK_VERSION(2, 10) // >= 2.10
156template <FdLike Fd, typename FreeFunc>
157inline auto async_sendmsg_zc(Fd fd, detail::FixedBuffer<const msghdr *> msg,
158 unsigned flags, FreeFunc &&func) {
159 auto op = make_zero_copy_op_awaiter(std::forward<FreeFunc>(func),
160 io_uring_prep_sendmsg_zc_fixed, fd,
161 msg.value, flags, msg.buf_index);
162 return detail::maybe_flag_fixed_fd(std::move(op), fd);
163}
164#endif
165
169template <FdLike Fd> inline auto async_fsync(Fd fd, unsigned fsync_flags) {
170 auto op = make_op_awaiter(io_uring_prep_fsync, fd, fsync_flags);
171 return detail::maybe_flag_fixed_fd(std::move(op), fd);
172}
173
177inline auto async_nop() { return make_op_awaiter(io_uring_prep_nop); }
178
182inline auto async_timeout(struct __kernel_timespec *ts, unsigned count,
183 unsigned flags) {
184 return make_op_awaiter(io_uring_prep_timeout, ts, count, flags);
185}
186
187#if !IO_URING_CHECK_VERSION(2, 4) // >= 2.4
188
192template <typename MultiShotFunc>
193inline auto async_timeout_multishot(struct __kernel_timespec *ts,
194 unsigned count, unsigned flags,
195 MultiShotFunc &&func) {
196 return make_multishot_op_awaiter(std::forward<MultiShotFunc>(func),
197 io_uring_prep_timeout, ts, count,
198 flags | IORING_TIMEOUT_MULTISHOT);
199}
200#endif
201
205template <FdLike Fd>
206inline auto async_accept(Fd fd, struct sockaddr *addr, socklen_t *addrlen,
207 int flags) {
208 auto op = make_op_awaiter(io_uring_prep_accept, fd, addr, addrlen, flags);
209 return detail::maybe_flag_fixed_fd(std::move(op), fd);
210}
211
215template <FdLike Fd>
216inline auto async_accept_direct(Fd fd, struct sockaddr *addr,
217 socklen_t *addrlen, int flags,
218 unsigned int file_index) {
219 auto op = make_op_awaiter(io_uring_prep_accept_direct, fd, addr, addrlen,
220 flags, file_index);
221 return detail::maybe_flag_fixed_fd(std::move(op), fd);
222}
223
227template <FdLike Fd, typename MultiShotFunc>
228inline auto async_multishot_accept(Fd fd, struct sockaddr *addr,
229 socklen_t *addrlen, int flags,
230 MultiShotFunc &&func) {
231 auto op = make_multishot_op_awaiter(std::forward<MultiShotFunc>(func),
232 io_uring_prep_multishot_accept, fd,
233 addr, addrlen, flags);
234 return detail::maybe_flag_fixed_fd(std::move(op), fd);
235}
236
240template <FdLike Fd, typename MultiShotFunc>
241inline auto async_multishot_accept_direct(Fd fd, struct sockaddr *addr,
242 socklen_t *addrlen, int flags,
243 MultiShotFunc &&func) {
244 auto op = make_multishot_op_awaiter(std::forward<MultiShotFunc>(func),
245 io_uring_prep_multishot_accept_direct,
246 fd, addr, addrlen, flags);
247 return detail::maybe_flag_fixed_fd(std::move(op), fd);
248}
249
253template <FdLike Fd> inline auto async_cancel_fd(Fd fd, unsigned int flags) {
254 if constexpr (detail::is_fixed_fd_v<Fd>) {
255 flags |= IORING_ASYNC_CANCEL_FD_FIXED;
256 }
257 return make_op_awaiter(io_uring_prep_cancel_fd, fd, flags);
258}
259
263inline auto async_link_timeout(struct __kernel_timespec *ts, unsigned flags) {
264 return make_op_awaiter(io_uring_prep_link_timeout, ts, flags);
265}
266
270template <FdLike Fd>
271inline auto async_connect(Fd fd, const struct sockaddr *addr,
272 socklen_t addrlen) {
273 auto op = make_op_awaiter(io_uring_prep_connect, fd, addr, addrlen);
274 return detail::maybe_flag_fixed_fd(std::move(op), fd);
275}
276
280inline auto async_files_update(int *fds, unsigned nr_fds, int offset) {
281 return make_op_awaiter(io_uring_prep_files_update, fds, nr_fds, offset);
282}
283
287template <FdLike Fd>
288inline auto async_fallocate(Fd fd, int mode, __u64 offset, __u64 len) {
289 auto op = make_op_awaiter(io_uring_prep_fallocate, fd, mode, offset, len);
290 return detail::maybe_flag_fixed_fd(std::move(op), fd);
291}
292
296inline auto async_openat(int dfd, const char *path, int flags, mode_t mode) {
297 return make_op_awaiter(io_uring_prep_openat, dfd, path, flags, mode);
298}
299
303inline auto async_openat_direct(int dfd, const char *path, int flags,
304 mode_t mode, unsigned file_index) {
305 return make_op_awaiter(io_uring_prep_openat_direct, dfd, path, flags, mode,
306 file_index);
307}
308
312inline auto async_open(const char *path, int flags, mode_t mode) {
313 return async_openat(AT_FDCWD, path, flags, mode);
314}
315
319inline auto async_open_direct(const char *path, int flags, mode_t mode,
320 unsigned file_index) {
321 return async_openat_direct(AT_FDCWD, path, flags, mode, file_index);
322}
323
327inline auto async_close(int fd) {
328 return make_op_awaiter(io_uring_prep_close, fd);
329}
330
334inline auto async_close(detail::FixedFd fd) {
335 return make_op_awaiter(io_uring_prep_close_direct, fd);
336}
337
341template <FdLike Fd, BufferLike Buffer>
342inline auto async_read(Fd fd, Buffer &&buf, __u64 offset) {
343 auto op =
344 make_op_awaiter(io_uring_prep_read, fd, buf.data(), buf.size(), offset);
345 return detail::maybe_flag_fixed_fd(std::move(op), fd);
346}
347
351template <FdLike Fd, BufferLike Buffer>
352inline auto async_read(Fd fd, detail::FixedBuffer<Buffer> buf, __u64 offset) {
353 auto op = make_op_awaiter(io_uring_prep_read_fixed, fd, buf.value.data(),
354 buf.value.size(), offset, buf.buf_index);
355 return detail::maybe_flag_fixed_fd(std::move(op), fd);
356}
357
361template <FdLike Fd, NotBundledBufferRing Buffer>
362inline auto async_read(Fd fd, Buffer &buf, __u64 offset) {
363 auto op = make_select_buffer_op_awaiter(&buf, io_uring_prep_read, fd,
364 nullptr, 0, offset);
365 return detail::maybe_flag_fixed_fd(std::move(op), fd);
366}
367
368#if !IO_URING_CHECK_VERSION(2, 6) // >= 2.6
372template <FdLike Fd, NotBundledBufferRing Buffer, typename MultiShotFunc>
373inline auto async_read_multishot(Fd fd, Buffer &buf, __u64 offset,
374 MultiShotFunc &&func) {
376 std::forward<MultiShotFunc>(func), &buf, io_uring_prep_read_multishot,
377 fd, 0, offset, buf.bgid());
378 return detail::maybe_flag_fixed_fd(std::move(op), fd);
379}
380#endif
381
385template <FdLike Fd, BufferLike Buffer>
386inline auto async_write(Fd fd, Buffer &&buf, __u64 offset) {
387 auto op = make_op_awaiter(io_uring_prep_write, fd, buf.data(), buf.size(),
388 offset);
389 return detail::maybe_flag_fixed_fd(std::move(op), fd);
390}
391
395template <FdLike Fd, BufferLike Buffer>
396inline auto async_write(Fd fd, detail::FixedBuffer<Buffer> buf, __u64 offset) {
397 auto op = make_op_awaiter(io_uring_prep_write_fixed, fd, buf.value.data(),
398 buf.value.size(), offset, buf.buf_index);
399 return detail::maybe_flag_fixed_fd(std::move(op), fd);
400}
401
405inline auto async_statx(int dfd, const char *path, int flags, unsigned mask,
406 struct statx *statxbuf) {
407 return make_op_awaiter(io_uring_prep_statx, dfd, path, flags, mask,
408 statxbuf);
409}
410
414template <FdLike Fd>
415inline auto async_fadvise(Fd fd, __u64 offset, off_t len, int advice) {
416 auto op = make_op_awaiter(io_uring_prep_fadvise, fd, offset, len, advice);
417 return detail::maybe_flag_fixed_fd(std::move(op), fd);
418}
419
420#if !IO_URING_CHECK_VERSION(2, 7) // >= 2.7
424template <FdLike Fd>
425inline auto async_fadvise64(Fd fd, __u64 offset, off_t len, int advice) {
426 auto op = make_op_awaiter(io_uring_prep_fadvise64, fd, offset, len, advice);
427 return detail::maybe_flag_fixed_fd(std::move(op), fd);
428}
429#endif
430
434inline auto async_madvise(void *addr, __u32 length, int advice) {
435 return make_op_awaiter(io_uring_prep_madvise, addr, length, advice);
436}
437
438#if !IO_URING_CHECK_VERSION(2, 7) // >= 2.7
442inline auto async_madvise64(void *addr, off_t length, int advice) {
443 auto op = make_op_awaiter(io_uring_prep_madvise64, addr, length, advice);
444 return op;
445}
446#endif
447
448namespace detail {
449
450inline void prep_sendto(io_uring_sqe *sqe, int sockfd, const void *buf,
451 size_t len, int flags, const struct sockaddr *addr,
452 socklen_t addrlen) {
453 io_uring_prep_send(sqe, sockfd, buf, len, flags);
454 io_uring_prep_send_set_addr(sqe, addr, addrlen);
455}
456
457inline void prep_send_fixed(io_uring_sqe *sqe, int sockfd, const void *buf,
458 size_t len, int flags, int buf_index) {
459 io_uring_prep_send(sqe, sockfd, buf, len, flags);
460 sqe->ioprio |= IORING_RECVSEND_FIXED_BUF;
461 sqe->buf_index = buf_index;
462}
463
464inline void prep_sendto_fixed(io_uring_sqe *sqe, int sockfd, const void *buf,
465 size_t len, int flags,
466 const struct sockaddr *addr, socklen_t addrlen,
467 int buf_index) {
468 prep_sendto(sqe, sockfd, buf, len, flags, addr, addrlen);
469 sqe->ioprio |= IORING_RECVSEND_FIXED_BUF;
470 sqe->buf_index = buf_index;
471}
472
473inline void prep_sendto_zc(io_uring_sqe *sqe, int sockfd, const void *buf,
474 size_t len, int flags, const struct sockaddr *addr,
475 socklen_t addrlen, unsigned zc_flags) {
476 io_uring_prep_send_zc(sqe, sockfd, buf, len, flags, zc_flags);
477 io_uring_prep_send_set_addr(sqe, addr, addrlen);
478}
479
480inline void prep_sendto_zc_fixed(io_uring_sqe *sqe, int sockfd, const void *buf,
481 size_t len, int flags,
482 const struct sockaddr *addr, socklen_t addrlen,
483 unsigned zc_flags, int buf_index) {
484 prep_sendto_zc(sqe, sockfd, buf, len, flags, addr, addrlen, zc_flags);
485 sqe->ioprio |= IORING_RECVSEND_FIXED_BUF;
486 sqe->buf_index = buf_index;
487}
488
489} // namespace detail
490
494template <FdLike Fd, BufferLike Buffer>
495inline auto async_send(Fd sockfd, Buffer &&buf, int flags) {
496 auto op = make_op_awaiter(io_uring_prep_send, sockfd, buf.data(),
497 buf.size(), flags);
498 return detail::maybe_flag_fixed_fd(std::move(op), sockfd);
499}
500
504template <FdLike Fd>
505inline auto async_send(Fd sockfd, ProvidedBufferQueue &buf, int flags) {
506 auto op = make_select_buffer_op_awaiter(&buf, io_uring_prep_send, sockfd,
507 nullptr, 0, flags);
508 return detail::maybe_flag_fixed_fd(std::move(op), sockfd);
509}
510
511#if !IO_URING_CHECK_VERSION(2, 7) // >= 2.7
515template <FdLike Fd>
516inline auto async_send(Fd sockfd, BundledProvidedBufferQueue &buf, int flags) {
517 auto op = make_bundle_select_buffer_op_awaiter(&buf, io_uring_prep_send,
518 sockfd, nullptr, 0, flags);
519 return detail::maybe_flag_fixed_fd(std::move(op), sockfd);
520}
521#endif
522
526template <FdLike Fd, BufferLike Buffer>
527inline auto async_sendto(Fd sockfd, Buffer &&buf, int flags,
528 const struct sockaddr *addr, socklen_t addrlen) {
529 auto op = make_op_awaiter(detail::prep_sendto, sockfd, buf.data(),
530 buf.size(), flags, addr, addrlen);
531 return detail::maybe_flag_fixed_fd(std::move(op), sockfd);
532}
533
537template <FdLike Fd>
538inline auto async_sendto(Fd sockfd, ProvidedBufferQueue &buf, int flags,
539 const struct sockaddr *addr, socklen_t addrlen) {
540 auto op = make_select_buffer_op_awaiter(&buf, detail::prep_sendto, sockfd,
541 nullptr, 0, flags, addr, addrlen);
542 return detail::maybe_flag_fixed_fd(std::move(op), sockfd);
543}
544
545#if !IO_URING_CHECK_VERSION(2, 7) // >= 2.7
549template <FdLike Fd>
550inline auto async_sendto(Fd sockfd, BundledProvidedBufferQueue &buf, int flags,
551 const struct sockaddr *addr, socklen_t addrlen) {
553 &buf, detail::prep_sendto, sockfd, nullptr, 0, flags, addr, addrlen);
554 return detail::maybe_flag_fixed_fd(std::move(op), sockfd);
555}
556#endif
557
561template <FdLike Fd, typename Buffer, typename FreeFunc>
562inline auto async_send_zc(Fd sockfd, Buffer &&buf, int flags, unsigned zc_flags,
563 FreeFunc &&func) {
565 std::forward<FreeFunc>(func), io_uring_prep_send_zc, sockfd, buf.data(),
566 buf.size(), flags, zc_flags);
567 return detail::maybe_flag_fixed_fd(std::move(op), sockfd);
568}
569
573template <FdLike Fd, BufferLike Buffer, typename FreeFunc>
574inline auto async_send_zc(Fd sockfd, detail::FixedBuffer<Buffer> buf, int flags,
575 unsigned zc_flags, FreeFunc &&func) {
577 std::forward<FreeFunc>(func), io_uring_prep_send_zc_fixed, sockfd,
578 buf.value.data(), buf.value.size(), flags, zc_flags, buf.buf_index);
579 return detail::maybe_flag_fixed_fd(std::move(op), sockfd);
580}
581
585template <FdLike Fd, BufferLike Buffer, typename FreeFunc>
586inline auto async_sendto_zc(Fd sockfd, Buffer &&buf, int flags,
587 const struct sockaddr *addr, socklen_t addrlen,
588 unsigned zc_flags, FreeFunc &&func) {
590 std::forward<FreeFunc>(func), detail::prep_sendto_zc, sockfd,
591 buf.data(), buf.size(), flags, addr, addrlen, zc_flags);
592 return detail::maybe_flag_fixed_fd(std::move(op), sockfd);
593}
594
598template <FdLike Fd, BufferLike Buffer, typename FreeFunc>
599inline auto async_sendto_zc(Fd sockfd, detail::FixedBuffer<Buffer> buf,
600 int flags, const struct sockaddr *addr,
601 socklen_t addrlen, unsigned zc_flags,
602 FreeFunc &&func) {
604 std::forward<FreeFunc>(func), detail::prep_sendto_zc_fixed, sockfd,
605 buf.value.data(), buf.value.size(), flags, addr, addrlen, zc_flags,
606 buf.buf_index);
607 return detail::maybe_flag_fixed_fd(std::move(op), sockfd);
608}
609
613template <FdLike Fd, BufferLike Buffer>
614inline auto async_recv(Fd sockfd, Buffer &&buf, int flags) {
615 auto op = make_op_awaiter(io_uring_prep_recv, sockfd, buf.data(),
616 buf.size(), flags);
617 return detail::maybe_flag_fixed_fd(std::move(op), sockfd);
618}
619
623template <FdLike Fd, NotBundledBufferRing Buffer>
624inline auto async_recv(Fd sockfd, Buffer &buf, int flags) {
625 auto op = make_select_buffer_op_awaiter(&buf, io_uring_prep_recv, sockfd,
626 nullptr, 0, flags);
627 return detail::maybe_flag_fixed_fd(std::move(op), sockfd);
628}
629
630#if !IO_URING_CHECK_VERSION(2, 7) // >= 2.7
634template <FdLike Fd, BundledBufferRing Buffer>
635inline auto async_recv(Fd sockfd, Buffer &buf, int flags) {
636 auto op = make_bundle_select_buffer_op_awaiter(&buf, io_uring_prep_recv,
637 sockfd, nullptr, 0, flags);
638 return detail::maybe_flag_fixed_fd(std::move(op), sockfd);
639}
640#endif
641
645template <FdLike Fd, NotBundledBufferRing Buffer, typename MultiShotFunc>
646inline auto async_recv_multishot(Fd sockfd, Buffer &buf, int flags,
647 MultiShotFunc &&func) {
649 std::forward<MultiShotFunc>(func), &buf, io_uring_prep_recv_multishot,
650 sockfd, nullptr, 0, flags);
651 return detail::maybe_flag_fixed_fd(std::move(op), sockfd);
652}
653
654#if !IO_URING_CHECK_VERSION(2, 7) // >= 2.7
658template <FdLike Fd, BundledBufferRing Buffer, typename MultiShotFunc>
659inline auto async_recv_multishot(Fd sockfd, Buffer &buf, int flags,
660 MultiShotFunc &&func) {
662 std::forward<MultiShotFunc>(func), &buf, io_uring_prep_recv_multishot,
663 sockfd, nullptr, 0, flags);
664 return detail::maybe_flag_fixed_fd(std::move(op), sockfd);
665}
666#endif
667
671inline auto async_openat2(int dfd, const char *path, struct open_how *how) {
672 return make_op_awaiter(io_uring_prep_openat2, dfd, path, how);
673}
674
678inline auto async_openat2_direct(int dfd, const char *path,
679 struct open_how *how, unsigned file_index) {
680 return make_op_awaiter(io_uring_prep_openat2_direct, dfd, path, how,
681 file_index);
682}
683
687template <FdLike Fd> inline auto async_shutdown(Fd fd, int how) {
688 auto op = make_op_awaiter(io_uring_prep_shutdown, fd, how);
689 return detail::maybe_flag_fixed_fd(std::move(op), fd);
690}
691
695inline auto async_unlinkat(int dfd, const char *path, int flags) {
696 return make_op_awaiter(io_uring_prep_unlinkat, dfd, path, flags);
697}
698
702inline auto async_unlink(const char *path, int flags) {
703 return async_unlinkat(AT_FDCWD, path, flags);
704}
705
709inline auto async_renameat(int olddfd, const char *oldpath, int newdfd,
710 const char *newpath, unsigned int flags) {
711 return make_op_awaiter(io_uring_prep_renameat, olddfd, oldpath, newdfd,
712 newpath, flags);
713}
714
718inline auto async_rename(const char *oldpath, const char *newpath) {
719 return async_renameat(AT_FDCWD, oldpath, AT_FDCWD, newpath, 0);
720}
721
725template <FdLike Fd>
726inline auto async_sync_file_range(Fd fd, unsigned len, __u64 offset,
727 int flags) {
728 auto op =
729 make_op_awaiter(io_uring_prep_sync_file_range, fd, len, offset, flags);
730 return detail::maybe_flag_fixed_fd(std::move(op), fd);
731}
732
736inline auto async_mkdirat(int dfd, const char *path, mode_t mode) {
737 return make_op_awaiter(io_uring_prep_mkdirat, dfd, path, mode);
738}
739
743inline auto async_mkdir(const char *path, mode_t mode) {
744 return async_mkdirat(AT_FDCWD, path, mode);
745}
746
750inline auto async_symlinkat(const char *target, int newdirfd,
751 const char *linkpath) {
752 return make_op_awaiter(io_uring_prep_symlinkat, target, newdirfd, linkpath);
753}
754
758inline auto async_symlink(const char *target, const char *linkpath) {
759 return async_symlinkat(target, AT_FDCWD, linkpath);
760}
761
765inline auto async_linkat(int olddfd, const char *oldpath, int newdfd,
766 const char *newpath, int flags) {
767 return make_op_awaiter(io_uring_prep_linkat, olddfd, oldpath, newdfd,
768 newpath, flags);
769}
770
774inline auto async_link(const char *oldpath, const char *newpath, int flags) {
775 return async_linkat(AT_FDCWD, oldpath, AT_FDCWD, newpath, flags);
776}
777
781inline auto async_getxattr(const char *name, char *value, const char *path,
782 unsigned int len) {
783 return make_op_awaiter(io_uring_prep_getxattr, name, value, path, len);
784}
785
789inline auto async_setxattr(const char *name, const char *value,
790 const char *path, int flags, unsigned int len) {
791 return make_op_awaiter(io_uring_prep_setxattr, name, value, path, flags,
792 len);
793}
794
798inline auto async_fgetxattr(int fd, const char *name, char *value,
799 unsigned int len) {
800 return make_op_awaiter(io_uring_prep_fgetxattr, fd, name, value, len);
801}
802
806inline auto async_fsetxattr(int fd, const char *name, const char *value,
807 int flags, unsigned int len) {
808 return make_op_awaiter(io_uring_prep_fsetxattr, fd, name, value, flags,
809 len);
810}
811
815inline auto async_socket(int domain, int type, int protocol,
816 unsigned int flags) {
817 return make_op_awaiter(io_uring_prep_socket, domain, type, protocol, flags);
818}
819
823inline auto async_socket_direct(int domain, int type, int protocol,
824 unsigned file_index, unsigned int flags) {
825 return make_op_awaiter(io_uring_prep_socket_direct, domain, type, protocol,
826 file_index, flags);
827}
828
829#if !IO_URING_CHECK_VERSION(2, 5) // >= 2.5
833template <FdLike Fd>
834inline auto async_cmd_sock(int cmd_op, Fd fd, int level, int optname,
835 void *optval, int optlen) {
836 auto op = make_op_awaiter(io_uring_prep_cmd_sock, cmd_op, fd, level,
837 optname, optval, optlen);
838 return detail::maybe_flag_fixed_fd(std::move(op), fd);
839}
840#endif
841
842#if !IO_URING_CHECK_VERSION(2, 6) // >= 2.6
846inline auto async_waitid(idtype_t idtype, id_t id, siginfo_t *infop,
847 int options, unsigned int flags) {
848 return make_op_awaiter(io_uring_prep_waitid, idtype, id, infop, options,
849 flags);
850}
851#endif
852
853#if !IO_URING_CHECK_VERSION(2, 6) // >= 2.6
857inline auto async_futex_wake(uint32_t *futex, uint64_t val, uint64_t mask,
858 uint32_t futex_flags, unsigned int flags) {
859 return make_op_awaiter(io_uring_prep_futex_wake, futex, val, mask,
860 futex_flags, flags);
861}
862#endif
863
864#if !IO_URING_CHECK_VERSION(2, 6) // >= 2.6
868inline auto async_futex_wait(uint32_t *futex, uint64_t val, uint64_t mask,
869 uint32_t futex_flags, unsigned int flags) {
870 return make_op_awaiter(io_uring_prep_futex_wait, futex, val, mask,
871 futex_flags, flags);
872}
873#endif
874
875#if !IO_URING_CHECK_VERSION(2, 6) // >= 2.6
879inline auto async_futex_waitv(struct futex_waitv *futex, uint32_t nr_futex,
880 unsigned int flags) {
881 return make_op_awaiter(io_uring_prep_futex_waitv, futex, nr_futex, flags);
882}
883#endif
884
885#if !IO_URING_CHECK_VERSION(2, 6) // >= 2.6
889inline auto async_fixed_fd_install(int fixed_fd, unsigned int flags) {
890 return make_op_awaiter(io_uring_prep_fixed_fd_install, fixed_fd, flags);
891}
892#endif
893
894#if !IO_URING_CHECK_VERSION(2, 4) // >= 2.4
898inline auto async_fixed_fd_send(FdTable &dst, int source_fd, int target_fd,
899 unsigned int flags) {
900 void *payload = nullptr;
901 if (static_cast<unsigned int>(target_fd) != CONDY_FILE_INDEX_ALLOC) {
902 // NOLINTNEXTLINE(performance-no-int-to-ptr)
903 payload = reinterpret_cast<void *>((target_fd + 1) << 3);
904 }
905 return make_op_awaiter(
906 io_uring_prep_msg_ring_fd, dst.ring_.ring_fd, source_fd, target_fd,
907 reinterpret_cast<uint64_t>(encode_work(payload, WorkType::SendFd)),
908 flags);
909}
910#endif
911
912#if !IO_URING_CHECK_VERSION(2, 6) // >= 2.6
916template <FdLike Fd> inline auto async_ftruncate(Fd fd, loff_t len) {
917 auto op = make_op_awaiter(io_uring_prep_ftruncate, fd, len);
918 return detail::maybe_flag_fixed_fd(std::move(op), fd);
919}
920#endif
921
922#if !IO_URING_CHECK_VERSION(2, 8) // >= 2.8
926template <FdLike Fd>
927inline auto async_cmd_discard(Fd fd, uint64_t offset, uint64_t nbytes) {
928 auto op = make_op_awaiter(io_uring_prep_cmd_discard, fd, offset, nbytes);
929 return detail::maybe_flag_fixed_fd(std::move(op), fd);
930}
931#endif
932
933#if !IO_URING_CHECK_VERSION(2, 7) // >= 2.7
937template <FdLike Fd>
938inline auto async_bind(Fd fd, struct sockaddr *addr, socklen_t addrlen) {
939 auto op = make_op_awaiter(io_uring_prep_bind, fd, addr, addrlen);
940 return detail::maybe_flag_fixed_fd(std::move(op), fd);
941}
942#endif
943
944#if !IO_URING_CHECK_VERSION(2, 7) // >= 2.7
948template <FdLike Fd> inline auto async_listen(Fd fd, int backlog) {
949 auto op = make_op_awaiter(io_uring_prep_listen, fd, backlog);
950 return detail::maybe_flag_fixed_fd(std::move(op), fd);
951}
952#endif
953
957inline auto async_epoll_ctl(int epfd, int fd, int op, struct epoll_event *ev) {
958 return make_op_awaiter(io_uring_prep_epoll_ctl, epfd, fd, op, ev);
959}
960
961#if !IO_URING_CHECK_VERSION(2, 10) // >= 2.10
965inline auto async_epoll_wait(int fd, struct epoll_event *events, int maxevents,
966 unsigned flags) {
967 return make_op_awaiter(io_uring_prep_epoll_wait, fd, events, maxevents,
968 flags);
969}
970#endif
971
972#if !IO_URING_CHECK_VERSION(2, 12) // >= 2.12
976inline auto async_pipe(int *fds, int pipe_flags) {
977 return make_op_awaiter(io_uring_prep_pipe, fds, pipe_flags);
978}
979#endif
980
981#if !IO_URING_CHECK_VERSION(2, 12) // >= 2.12
985inline auto async_pipe_direct(int *fds, int pipe_flags,
986 unsigned int file_index) {
987 return make_op_awaiter(io_uring_prep_pipe_direct, fds, pipe_flags,
988 file_index);
989}
990#endif
991
992} // namespace condy
Helper functions for composing asynchronous operations.
Provided buffer queue.
Definition provided_buffers.hpp:177
Helper functions for asynchronous operations.
#define CONDY_FILE_INDEX_ALLOC
Placeholder to let io_uring allocate a direct file descriptor.
Definition helpers.hpp:20
The main namespace for the Condy library.
Definition condy.hpp:28
auto async_read_multishot(Fd fd, Buffer &buf, __u64 offset, MultiShotFunc &&func)
See io_uring_prep_read_multishot.
Definition async_operations.hpp:373
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 async_symlinkat(const char *target, int newdirfd, const char *linkpath)
See io_uring_prep_symlinkat.
Definition async_operations.hpp:750
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 async_splice(Fd1 fd_in, int64_t off_in, Fd2 fd_out, int64_t off_out, unsigned int nbytes, unsigned int splice_flags)
See io_uring_prep_splice.
Definition async_operations.hpp:39
auto async_fsetxattr(int fd, const char *name, const char *value, int flags, unsigned int len)
See io_uring_prep_fsetxattr.
Definition async_operations.hpp:806
auto async_fadvise(Fd fd, __u64 offset, off_t len, int advice)
See io_uring_prep_fadvise.
Definition async_operations.hpp:415
auto async_writev(Fd fd, const struct iovec *iovecs, unsigned int nr_vecs, __u64 offset, int flags)
See io_uring_prep_writev2.
Definition async_operations.hpp:91
auto async_fixed_fd_install(int fixed_fd, unsigned int flags)
See io_uring_prep_fixed_fd_install.
Definition async_operations.hpp:889
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 async_socket_direct(int domain, int type, int protocol, unsigned file_index, unsigned int flags)
See io_uring_prep_socket_direct.
Definition async_operations.hpp:823
auto async_madvise64(void *addr, off_t length, int advice)
See io_uring_prep_madvise64.
Definition async_operations.hpp:442
auto async_fsync(Fd fd, unsigned fsync_flags)
See io_uring_prep_fsync.
Definition async_operations.hpp:169
auto async_ftruncate(Fd fd, loff_t len)
See io_uring_prep_ftruncate.
Definition async_operations.hpp:916
auto async_recvmsg(Fd fd, struct msghdr *msg, unsigned flags)
See io_uring_prep_recvmsg.
Definition async_operations.hpp:115
auto async_openat2(int dfd, const char *path, struct open_how *how)
See io_uring_prep_openat2.
Definition async_operations.hpp:671
auto async_open_direct(const char *path, int flags, mode_t mode, unsigned file_index)
See io_uring_prep_openat_direct.
Definition async_operations.hpp:319
auto async_write(Fd fd, Buffer &&buf, __u64 offset)
See io_uring_prep_write.
Definition async_operations.hpp:386
auto async_getxattr(const char *name, char *value, const char *path, unsigned int len)
See io_uring_prep_getxattr.
Definition async_operations.hpp:781
auto async_unlinkat(int dfd, const char *path, int flags)
See io_uring_prep_unlinkat.
Definition async_operations.hpp:695
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 async_openat_direct(int dfd, const char *path, int flags, mode_t mode, unsigned file_index)
See io_uring_prep_openat_direct.
Definition async_operations.hpp:303
auto async_epoll_ctl(int epfd, int fd, int op, struct epoll_event *ev)
See io_uring_prep_epoll_ctl.
Definition async_operations.hpp:957
auto async_mkdir(const char *path, mode_t mode)
See io_uring_prep_mkdirat.
Definition async_operations.hpp:743
auto async_fgetxattr(int fd, const char *name, char *value, unsigned int len)
See io_uring_prep_fgetxattr.
Definition async_operations.hpp:798
auto async_statx(int dfd, const char *path, int flags, unsigned mask, struct statx *statxbuf)
See io_uring_prep_statx.
Definition async_operations.hpp:405
auto async_sendto_zc(Fd sockfd, Buffer &&buf, int flags, const struct sockaddr *addr, socklen_t addrlen, unsigned zc_flags, FreeFunc &&func)
See io_uring_prep_send_zc and io_uring_prep_send_set_addr.
Definition async_operations.hpp:586
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 async_cmd_discard(Fd fd, uint64_t offset, uint64_t nbytes)
See io_uring_prep_cmd_discard.
Definition async_operations.hpp:927
auto async_link(const char *oldpath, const char *newpath, int flags)
See io_uring_prep_linkat.
Definition async_operations.hpp:774
auto async_multishot_accept_direct(Fd fd, struct sockaddr *addr, socklen_t *addrlen, int flags, MultiShotFunc &&func)
See io_uring_prep_multishot_accept_direct.
Definition async_operations.hpp:241
auto async_sendto(Fd sockfd, Buffer &&buf, int flags, const struct sockaddr *addr, socklen_t addrlen)
See io_uring_prep_send and io_uring_prep_send_set_addr.
Definition async_operations.hpp:527
auto async_futex_wake(uint32_t *futex, uint64_t val, uint64_t mask, uint32_t futex_flags, unsigned int flags)
See io_uring_prep_futex_wake.
Definition async_operations.hpp:857
auto async_recv_multishot(Fd sockfd, Buffer &buf, int flags, MultiShotFunc &&func)
See io_uring_prep_recv_multishot.
Definition async_operations.hpp:646
auto async_recv(Fd sockfd, Buffer &&buf, int flags)
See io_uring_prep_recv.
Definition async_operations.hpp:614
auto async_multishot_accept(Fd fd, struct sockaddr *addr, socklen_t *addrlen, int flags, MultiShotFunc &&func)
See io_uring_prep_multishot_accept.
Definition async_operations.hpp:228
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
auto async_fallocate(Fd fd, int mode, __u64 offset, __u64 len)
See io_uring_prep_fallocate.
Definition async_operations.hpp:288
auto async_madvise(void *addr, __u32 length, int advice)
See io_uring_prep_madvise.
Definition async_operations.hpp:434
auto async_epoll_wait(int fd, struct epoll_event *events, int maxevents, unsigned flags)
See io_uring_prep_epoll_wait.
Definition async_operations.hpp:965
auto async_symlink(const char *target, const char *linkpath)
See io_uring_prep_symlinkat.
Definition async_operations.hpp:758
auto async_sync_file_range(Fd fd, unsigned len, __u64 offset, int flags)
See io_uring_prep_sync_file_range.
Definition async_operations.hpp:726
auto async_fadvise64(Fd fd, __u64 offset, off_t len, int advice)
See io_uring_prep_fadvise64.
Definition async_operations.hpp:425
auto async_bind(Fd fd, struct sockaddr *addr, socklen_t addrlen)
See io_uring_prep_bind.
Definition async_operations.hpp:938
auto async_connect(Fd fd, const struct sockaddr *addr, socklen_t addrlen)
See io_uring_prep_connect.
Definition async_operations.hpp:271
auto async_waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options, unsigned int flags)
See io_uring_prep_waitid.
Definition async_operations.hpp:846
auto async_files_update(int *fds, unsigned nr_fds, int offset)
See io_uring_prep_files_update.
Definition async_operations.hpp:280
auto async_cmd_sock(int cmd_op, Fd fd, int level, int optname, void *optval, int optlen)
See io_uring_prep_cmd_sock.
Definition async_operations.hpp:834
auto async_tee(Fd1 fd_in, Fd2 fd_out, unsigned int nbytes, unsigned int splice_flags)
See io_uring_prep_tee.
Definition async_operations.hpp:53
auto async_recvmsg_multishot(Fd fd, struct msghdr *msg, unsigned flags, Buffer &buf, MultiShotFunc &&func)
See io_uring_prep_recvmsg_multishot.
Definition async_operations.hpp:124
auto async_futex_wait(uint32_t *futex, uint64_t val, uint64_t mask, uint32_t futex_flags, unsigned int flags)
See io_uring_prep_futex_wait.
Definition async_operations.hpp:868
auto async_sendmsg(Fd fd, const struct msghdr *msg, unsigned flags)
See io_uring_prep_sendmsg.
Definition async_operations.hpp:136
auto async_read(Fd fd, Buffer &&buf, __u64 offset)
See io_uring_prep_read.
Definition async_operations.hpp:342
auto async_cancel_fd(Fd fd, unsigned int flags)
See io_uring_prep_cancel_fd.
Definition async_operations.hpp:253
auto async_pipe_direct(int *fds, int pipe_flags, unsigned int file_index)
See io_uring_prep_pipe_direct.
Definition async_operations.hpp:985
auto async_link_timeout(struct __kernel_timespec *ts, unsigned flags)
See io_uring_prep_link_timeout.
Definition async_operations.hpp:263
auto async_nop()
See io_uring_prep_nop.
Definition async_operations.hpp:177
auto async_sendmsg_zc(Fd fd, const struct msghdr *msg, unsigned flags, FreeFunc &&func)
See io_uring_prep_sendmsg_zc.
Definition async_operations.hpp:145
auto async_close(int fd)
See io_uring_prep_close.
Definition async_operations.hpp:327
auto async_open(const char *path, int flags, mode_t mode)
See io_uring_prep_openat.
Definition async_operations.hpp:312
auto flag(Awaiter &&awaiter)
Decorates an awaiter with specific io_uring sqe flags.
Definition awaiter_operations.hpp:146
auto async_listen(Fd fd, int backlog)
See io_uring_prep_listen.
Definition async_operations.hpp:948
auto async_send(Fd sockfd, Buffer &&buf, int flags)
See io_uring_prep_send.
Definition async_operations.hpp:495
auto async_renameat(int olddfd, const char *oldpath, int newdfd, const char *newpath, unsigned int flags)
See io_uring_prep_renameat.
Definition async_operations.hpp:709
auto async_accept_direct(Fd fd, struct sockaddr *addr, socklen_t *addrlen, int flags, unsigned int file_index)
See io_uring_prep_accept_direct.
Definition async_operations.hpp:216
auto async_timeout(struct __kernel_timespec *ts, unsigned count, unsigned flags)
See io_uring_prep_timeout.
Definition async_operations.hpp:182
auto async_rename(const char *oldpath, const char *newpath)
See io_uring_prep_renameat.
Definition async_operations.hpp:718
auto async_setxattr(const char *name, const char *value, const char *path, int flags, unsigned int len)
See io_uring_prep_setxattr.
Definition async_operations.hpp:789
auto async_send_zc(Fd sockfd, Buffer &&buf, int flags, unsigned zc_flags, FreeFunc &&func)
See io_uring_prep_send_zc.
Definition async_operations.hpp:562
auto async_openat2_direct(int dfd, const char *path, struct open_how *how, unsigned file_index)
See io_uring_prep_openat2_direct.
Definition async_operations.hpp:678
auto async_unlink(const char *path, int flags)
See io_uring_prep_unlinkat.
Definition async_operations.hpp:702
auto async_accept(Fd fd, struct sockaddr *addr, socklen_t *addrlen, int flags)
See io_uring_prep_accept.
Definition async_operations.hpp:206
auto async_mkdirat(int dfd, const char *path, mode_t mode)
See io_uring_prep_mkdirat.
Definition async_operations.hpp:736
auto async_readv(Fd fd, const struct iovec *iovecs, unsigned nr_vecs, __u64 offset, int flags)
See io_uring_prep_readv2.
Definition async_operations.hpp:67
auto async_openat(int dfd, const char *path, int flags, mode_t mode)
See io_uring_prep_openat.
Definition async_operations.hpp:296
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 async_timeout_multishot(struct __kernel_timespec *ts, unsigned count, unsigned flags, MultiShotFunc &&func)
See io_uring_prep_timeout.
Definition async_operations.hpp:193
auto async_linkat(int olddfd, const char *oldpath, int newdfd, const char *newpath, int flags)
See io_uring_prep_linkat.
Definition async_operations.hpp:765
auto async_pipe(int *fds, int pipe_flags)
See io_uring_prep_pipe.
Definition async_operations.hpp:976
auto async_fixed_fd_send(FdTable &dst, int source_fd, int target_fd, unsigned int flags)
See io_uring_prep_msg_ring_fd.
Definition async_operations.hpp:898
auto async_futex_waitv(struct futex_waitv *futex, uint32_t nr_futex, unsigned int flags)
See io_uring_prep_futex_waitv.
Definition async_operations.hpp:879
auto async_shutdown(Fd fd, int how)
See io_uring_prep_shutdown.
Definition async_operations.hpp:687
auto async_socket(int domain, int type, int protocol, unsigned int flags)
See io_uring_prep_socket.
Definition async_operations.hpp:815
Support for io_uring provided buffers.