Iros
 
Loading...
Searching...
No Matches
io_uring_context.h
Go to the documentation of this file.
1#pragma once
2
3#include "di/assert/prelude.h"
18#include "di/function/prelude.h"
19#include "di/meta/operations.h"
21#include "di/util/addressof.h"
24#include "dius/error.h"
25#include "dius/linux/error.h"
26#include "dius/linux/io_uring.h"
28#include "dius/net/address.h"
29#include "dius/net/socket.h"
30#include "dius/sync_file.h"
31
32#ifdef DIUS_USE_RUNTIME
33#include <linux/socket.h>
34#include <linux/un.h>
35#else
36#include <sys/socket.h>
37#include <sys/un.h>
38#endif
39
40namespace dius::linux {
41struct IoUringContext;
42struct IoUringContextImpl;
44struct IoUringScheduler;
45struct ScheduleSender;
46struct OpenSender;
47struct AcceptSender;
48struct MakeSocketSender;
49
50template<di::concepts::Invocable<io_uring::SQE*> Fun>
51static void enqueue_io_operation(IoUringContext*, OperationStateBase* op, Fun&& function);
52
54
56
58public:
59 virtual void execute() = 0;
60 virtual void did_complete(io_uring::CQE const*) {}
61};
62
84
86public:
87 IoUringContext* parent { nullptr };
88
89private:
91
92 constexpr friend auto operator==(IoUringScheduler const&, IoUringScheduler const&) -> bool = default;
93};
94
95struct Env {
96 IoUringContext* parent { nullptr };
97
98 template<typename CPO>
99 constexpr friend auto tag_invoke(di::execution::GetCompletionScheduler<CPO>, Env const& self) {
100 return get_scheduler(self.parent);
101 }
102};
103
105public:
106 using is_sender = void;
107
110
111 IoUringContext* parent { nullptr };
112 int file_descriptor { -1 };
115
116private:
117 template<typename Rec>
118 struct OperationStateT {
121 di::Optional<u64> offset, Rec receiver)
122 : m_parent(parent)
123 , m_file_descriptor(file_descriptor)
124 , m_buffer(buffer)
125 , m_offset(offset)
126 , m_receiver(di::move(receiver)) {}
127
128 void execute() override {
129 if (di::execution::get_stop_token(m_receiver).stop_requested()) {
130 di::execution::set_stopped(di::move(m_receiver));
131 } else {
132 // Enqueue io_uring sqe with the read request.
133 enqueue_io_operation(m_parent, this, [&](auto* sqe) {
134 sqe->opcode = IORING_OP_READ;
135 sqe->fd = m_file_descriptor;
136 sqe->off = m_offset.value_or((u64) -1);
137 sqe->addr = reinterpret_cast<u64>(m_buffer.data());
138 sqe->len = m_buffer.size();
139 });
140 }
141 }
142
143 void did_complete(io_uring::CQE const* cqe) override {
144 if (cqe->res < 0) {
145 di::execution::set_error(di::move(m_receiver), di::Error(PosixError(-cqe->res)));
146 } else {
147 di::execution::set_value(di::move(m_receiver), static_cast<size_t>(cqe->res));
148 }
149 }
150
151 private:
153 enqueue_operation(self.m_parent, di::addressof(self));
154 }
155
156 IoUringContext* m_parent;
157 int m_file_descriptor;
158 di::Span<di::Byte> m_buffer;
159 di::Optional<u64> m_offset;
160 [[no_unique_address]] Rec m_receiver;
161 };
162 };
163
164 template<di::ReceiverOf<CompletionSignatures> Receiver>
165 using OperationState = di::meta::Type<OperationStateT<Receiver>>;
166
167 template<di::ReceiverOf<CompletionSignatures> Receiver>
168 friend auto tag_invoke(di::Tag<di::execution::connect>, ReadSomeSender self, Receiver receiver) {
169 return OperationState<Receiver> { self.parent, self.file_descriptor, self.buffer, self.offset,
170 di::move(receiver) };
171 }
172
173 constexpr friend auto tag_invoke(di::Tag<di::execution::get_env>, ReadSomeSender const& self) {
174 return Env(self.parent);
175 }
176};
177
179public:
180 using is_sender = void;
181
184
185 IoUringContext* parent { nullptr };
186 int file_descriptor { -1 };
189
190private:
191 template<typename Rec>
192 struct OperationStateT {
195 di::Optional<u64> offset, Rec receiver)
196 : m_parent(parent)
197 , m_file_descriptor(file_descriptor)
198 , m_buffer(buffer)
199 , m_offset(offset)
200 , m_receiver(di::move(receiver)) {}
201
202 void execute() override {
203 if (di::execution::get_stop_token(m_receiver).stop_requested()) {
204 di::execution::set_stopped(di::move(m_receiver));
205 } else {
206 // Enqueue io_uring sqe with the write request.
207 enqueue_io_operation(m_parent, this, [&](auto* sqe) {
208 sqe->opcode = IORING_OP_WRITE;
209 sqe->fd = m_file_descriptor;
210 sqe->off = m_offset.value_or((u64) -1);
211 sqe->addr = reinterpret_cast<u64>(m_buffer.data());
212 sqe->len = m_buffer.size();
213 });
214 }
215 }
216
217 void did_complete(io_uring::CQE const* cqe) override {
218 if (cqe->res < 0) {
219 di::execution::set_error(di::move(m_receiver), di::Error(PosixError(-cqe->res)));
220 } else {
221 di::execution::set_value(di::move(m_receiver), static_cast<size_t>(cqe->res));
222 }
223 }
224
225 private:
227 enqueue_operation(self.m_parent, di::addressof(self));
228 }
229
230 IoUringContext* m_parent;
231 int m_file_descriptor;
233 di::Optional<u64> m_offset;
234 [[no_unique_address]] Rec m_receiver;
235 };
236 };
237
238 template<di::ReceiverOf<CompletionSignatures> Receiver>
239 using OperationState = di::meta::Type<OperationStateT<Receiver>>;
240
241 template<di::ReceiverOf<CompletionSignatures> Receiver>
242 friend auto tag_invoke(di::Tag<di::execution::connect>, WriteSomeSender self, Receiver receiver) {
243 return OperationState<Receiver> { self.parent, self.file_descriptor, self.buffer, self.offset,
244 di::move(receiver) };
245 }
246
247 constexpr friend auto tag_invoke(di::Tag<di::execution::get_env>, WriteSomeSender const& self) {
248 return Env(self.parent);
249 }
250};
251
253public:
254 using is_sender = void;
255
257
258 IoUringContext* parent { nullptr };
259 int file_descriptor { -1 };
260
261private:
262 template<typename Rec>
263 struct OperationStateT {
265 explicit Type(IoUringContext* parent, int file_descriptor, Rec receiver)
266 : m_parent(parent), m_file_descriptor(file_descriptor), m_receiver(di::move(receiver)) {}
267
268 void execute() override {
269 if (di::execution::get_stop_token(m_receiver).stop_requested()) {
270 di::execution::set_stopped(di::move(m_receiver));
271 } else {
272 // Enqueue io_uring sqe with the close request.
273 enqueue_io_operation(m_parent, this, [&](auto* sqe) {
274 sqe->opcode = IORING_OP_CLOSE;
275 sqe->fd = m_file_descriptor;
276 });
277 }
278 }
279
280 void did_complete(io_uring::CQE const* cqe) override {
281 if (cqe->res < 0) {
282 di::execution::set_error(di::move(m_receiver), di::Error(PosixError(-cqe->res)));
283 } else {
284 di::execution::set_value(di::move(m_receiver));
285 }
286 }
287
288 private:
290 enqueue_operation(self.m_parent, di::addressof(self));
291 }
292
293 IoUringContext* m_parent;
294 int m_file_descriptor;
295 [[no_unique_address]] Rec m_receiver;
296 };
297 };
298
299 template<di::ReceiverOf<CompletionSignatures> Receiver>
300 using OperationState = di::meta::Type<OperationStateT<Receiver>>;
301
302 template<di::ReceiverOf<CompletionSignatures> Receiver>
303 friend auto tag_invoke(di::Tag<di::execution::connect>, CloseSender self, Receiver receiver) {
304 return OperationState<Receiver> { self.parent, self.file_descriptor, di::move(receiver) };
305 }
306
307 constexpr friend auto tag_invoke(di::Tag<di::execution::get_env>, CloseSender const& self) {
308 return Env(self.parent);
309 }
310};
311
313public:
314 using is_sender = void;
315
317
318 IoUringContext* parent { nullptr };
319 int file_descriptor { -1 };
321
322private:
323 template<typename Rec>
324 struct OperationStateT {
327 : m_parent(parent), m_file_descriptor(file_descriptor), m_receiver(di::move(receiver)) {
328 if (address.path().size() < 108 - 1) {
329 sockaddr_un addr = {};
330 addr.sun_family = 1;
331 di::copy(address.path(), addr.sun_path);
332 m_address = addr;
333 }
334 }
335
336 void execute() override {
337 if (di::execution::get_stop_token(m_receiver).stop_requested()) {
338 di::execution::set_stopped(di::move(m_receiver));
339 } else {
340 // If the path was too long, fail fast.
341 if (!m_address) {
342 di::execution::set_error(di::move(m_receiver), di::Error(dius::PosixError::FilenameTooLong));
343 return;
344 }
345
346 // Enqueue io_uring sqe with the close request.
347 enqueue_io_operation(m_parent, this, [&](auto* sqe) {
348 sqe->opcode = IORING_OP_CONNECT;
349 sqe->fd = m_file_descriptor;
350 sqe->addr = (u64) di::addressof(m_address.value());
351 sqe->off = sizeof(m_address.value());
352 });
353 }
354 }
355
356 void did_complete(io_uring::CQE const* cqe) override {
357 if (cqe->res < 0) {
358 di::execution::set_error(di::move(m_receiver), di::Error(PosixError(-cqe->res)));
359 } else {
360 di::execution::set_value(di::move(m_receiver));
361 }
362 }
363
364 private:
366 enqueue_operation(self.m_parent, di::addressof(self));
367 }
368
369 IoUringContext* m_parent { nullptr };
370 int m_file_descriptor { -1 };
372 [[no_unique_address]] Rec m_receiver;
373 };
374 };
375
376 template<di::ReceiverOf<CompletionSignatures> Receiver>
377 using OperationState = di::meta::Type<OperationStateT<Receiver>>;
378
379 template<di::ReceiverOf<CompletionSignatures> Receiver>
380 friend auto tag_invoke(di::Tag<di::execution::connect>, ConnectSender self, Receiver receiver) {
381 return OperationState<Receiver> { self.parent, self.file_descriptor, di::move(self.address),
382 di::move(receiver) };
383 }
384
385 constexpr friend auto tag_invoke(di::Tag<di::execution::get_env>, ConnectSender const& self) {
386 return Env(self.parent);
387 }
388};
389
391public:
392 using is_sender = void;
393
395
396 IoUringContext* parent { nullptr };
397 int file_descriptor { -1 };
399
400private:
401 template<typename Rec>
402 struct OperationStateT {
405 : m_parent(parent), m_file_descriptor(file_descriptor), m_receiver(di::move(receiver)) {
406 if (address.path().size() < 108 - 1) {
407 sockaddr_un addr = {};
408 addr.sun_family = 1;
409 di::copy(address.path(), addr.sun_path);
410 m_address = addr;
411 }
412 }
413
414 void execute() override {
415 if (di::execution::get_stop_token(m_receiver).stop_requested()) {
416 di::execution::set_stopped(di::move(m_receiver));
417 } else {
418 // If the path was too long, fail fast.
419 if (!m_address) {
420 di::execution::set_error(di::move(m_receiver), di::Error(dius::PosixError::FilenameTooLong));
421 return;
422 }
423
424 // io_uring doesn't support bind() and listen()...
425 auto result = system::system_call<int>(system::Number::bind, m_file_descriptor,
426 di::addressof(m_address.value()), sizeof(m_address.value()));
427 if (!result.has_value()) {
428 di::execution::set_error(di::move(m_receiver), di::Error(di::move(result).error()));
429 } else {
430 di::execution::set_value(di::move(m_receiver));
431 }
432 }
433 }
434
435 private:
437 enqueue_operation(self.m_parent, di::addressof(self));
438 }
439
440 IoUringContext* m_parent { nullptr };
441 int m_file_descriptor { -1 };
443 [[no_unique_address]] Rec m_receiver;
444 };
445 };
446
447 template<di::ReceiverOf<CompletionSignatures> Receiver>
448 using OperationState = di::meta::Type<OperationStateT<Receiver>>;
449
450 template<di::ReceiverOf<CompletionSignatures> Receiver>
451 friend auto tag_invoke(di::Tag<di::execution::connect>, BindSender self, Receiver receiver) {
452 return OperationState<Receiver> { self.parent, self.file_descriptor, di::move(self.address),
453 di::move(receiver) };
454 }
455
456 constexpr friend auto tag_invoke(di::Tag<di::execution::get_env>, BindSender const& self) {
457 return Env(self.parent);
458 }
459};
460
462public:
463 using is_sender = void;
464
466
467 IoUringContext* parent { nullptr };
468 int file_descriptor { -1 };
469 int count { 0 };
470
471private:
472 template<typename Rec>
473 struct OperationStateT {
475 explicit Type(IoUringContext* parent, int file_descriptor, int count, Rec receiver)
476 : m_parent(parent)
477 , m_file_descriptor(file_descriptor)
478 , m_count(count)
479 , m_receiver(di::move(receiver)) {}
480
481 void execute() override {
482 if (di::execution::get_stop_token(m_receiver).stop_requested()) {
483 di::execution::set_stopped(di::move(m_receiver));
484 } else {
485 // io_uring doesn't support bind() and listen()...
486 auto result = system::system_call<int>(system::Number::listen, m_file_descriptor, m_count);
487 if (!result.has_value()) {
488 di::execution::set_error(di::move(m_receiver), di::Error(di::move(result).error()));
489 } else {
490 di::execution::set_value(di::move(m_receiver));
491 }
492 }
493 }
494
495 private:
497 enqueue_operation(self.m_parent, di::addressof(self));
498 }
499
500 IoUringContext* m_parent { nullptr };
501 int m_file_descriptor { -1 };
502 int m_count {};
503 [[no_unique_address]] Rec m_receiver;
504 };
505 };
506
507 template<di::ReceiverOf<CompletionSignatures> Receiver>
509
510 template<di::ReceiverOf<CompletionSignatures> Receiver>
511 friend auto tag_invoke(di::Tag<di::execution::connect>, ListenSender self, Receiver receiver) {
512 return OperationState<Receiver> { self.parent, self.file_descriptor, self.count, di::move(receiver) };
513 }
514
515 constexpr friend auto tag_invoke(di::Tag<di::execution::get_env>, ListenSender const& self) {
516 return Env(self.parent);
517 }
518};
519
521public:
522 using is_sender = void;
523
525
526 IoUringContext* parent { nullptr };
527 int file_descriptor { -1 };
529
530private:
531 template<typename Rec>
532 struct OperationStateT {
535 : m_parent(parent), m_file_descriptor(file_descriptor), m_how(how), m_receiver(di::move(receiver)) {}
536
537 void execute() override {
538 if (di::execution::get_stop_token(m_receiver).stop_requested()) {
539 di::execution::set_stopped(di::move(m_receiver));
540 } else {
541 // Enqueue io_uring sqe with the close request.
542 enqueue_io_operation(m_parent, this, [&](auto* sqe) {
543 sqe->opcode = IORING_OP_SHUTDOWN;
544 sqe->fd = m_file_descriptor;
545 sqe->len = (u32) m_how;
546 });
547 }
548 }
549
550 void did_complete(io_uring::CQE const* cqe) override {
551 if (cqe->res < 0) {
552 di::execution::set_error(di::move(m_receiver), di::Error(PosixError(-cqe->res)));
553 } else {
554 di::execution::set_value(di::move(m_receiver));
555 }
556 }
557
558 private:
560 enqueue_operation(self.m_parent, di::addressof(self));
561 }
562
563 IoUringContext* m_parent { nullptr };
564 int m_file_descriptor { -1 };
565 net::Shutdown m_how {};
566 [[no_unique_address]] Rec m_receiver;
567 };
568 };
569
570 template<di::ReceiverOf<CompletionSignatures> Receiver>
572
573 template<di::ReceiverOf<CompletionSignatures> Receiver>
574 friend auto tag_invoke(di::Tag<di::execution::connect>, ShutdownSender self, Receiver receiver) {
575 return OperationState<Receiver> { self.parent, self.file_descriptor, self.how, di::move(receiver) };
576 }
577
578 constexpr friend auto tag_invoke(di::Tag<di::execution::get_env>, ShutdownSender const& self) {
579 return Env(self.parent);
580 }
581};
582
584public:
585 using is_sender = void;
586
588
589 IoUringContext* parent { nullptr };
590
591private:
592 template<typename Rec>
593 struct OperationStateT {
595 public:
596 Type(IoUringContext* parent, Rec&& receiver) : m_parent(parent), m_receiver(di::move(receiver)) {}
597
598 void execute() override {
599 if (di::execution::get_stop_token(m_receiver).stop_requested()) {
600 di::execution::set_stopped(di::move(m_receiver));
601 } else {
602 di::execution::set_value(di::move(m_receiver));
603 }
604 }
605
606 private:
608 enqueue_operation(self.m_parent, di::addressof(self));
609 }
610
611 IoUringContext* m_parent { nullptr };
612 [[no_unique_address]] Rec m_receiver;
613 };
614 };
615
616 template<di::Receiver Rec>
617 using OperationState = di::meta::Type<OperationStateT<Rec>>;
618
619 template<di::ReceiverOf<CompletionSignatures> Rec>
621 return OperationState<Rec> { self.parent, di::move(receiver) };
622 }
623
624 constexpr friend auto tag_invoke(di::Tag<di::execution::get_env>, ScheduleSender const& self) {
625 return Env { self.parent };
626 }
627};
628
630public:
632 : m_parent(parent), m_path(di::move(path)), m_mode(mode), m_create_mode(create_mode) {}
633
634 auto parent() const -> IoUringContext* { return m_parent; }
635 auto path() const -> di::Path const& { return m_path; }
636 auto mode() const -> OpenMode { return m_mode; }
637 auto create_mode() const -> u16 { return m_create_mode; }
638
639 auto fd() const -> int { return m_fd; }
640 void set_fd(int fd) { m_fd = fd; }
641
642private:
644 di::Optional<u64> offset) {
645 return ReadSomeSender { self.m_parent, self.m_fd, buffer, offset };
646 }
647
649 di::Optional<u64> offset) {
650 return WriteSomeSender { self.m_parent, self.m_fd, buffer, offset };
651 }
652
653 IoUringContext* m_parent;
654 di::Path m_path;
655 OpenMode m_mode;
656 u16 m_create_mode;
657 int m_fd { -1 };
658};
659
661public:
662 explicit AcceptSocket(int base_fd) : m_base_fd(base_fd) {}
663
664 auto base_fd() const -> int { return m_base_fd; }
665
666private:
667 int m_base_fd { -1 };
668};
669
670template<typename Base>
672 : public di::Immovable
673 , public Base {
674public:
675 template<typename... Args>
676 requires(di::concepts::ConstructibleFrom<Base, Args...>)
677 explicit AsyncSocket(IoUringContext* context, Args&&... args)
678 : Base(di::forward<Args>(args)...), m_parent(context) {}
679
680 auto parent() const -> IoUringContext* { return m_parent; }
681
682 auto fd() const -> int { return m_fd; }
683 void set_fd(int fd) { m_fd = fd; }
684
685private:
688 return ReadSomeSender { self.m_parent, self.m_fd, buffer, {} };
689 }
690
693 return WriteSomeSender { self.m_parent, self.m_fd, buffer, {} };
694 }
695
697 return BindSender { self.m_parent, self.m_fd, di::move(address) };
698 }
699
701 return ConnectSender { self.m_parent, self.m_fd, di::move(address) };
702 }
703
705 return ListenSender { self.m_parent, self.m_fd, count };
706 }
707
709 return ShutdownSender { self.m_parent, self.m_fd, how };
710 }
711
713 return di::make_deferred<AsyncSocket<AcceptSocket>>(self.m_parent, self.m_fd);
714 }
715
716 IoUringContext* m_parent;
717 int m_fd { -1 };
718};
719
721public:
722 using is_sender = void;
723
726
729
730private:
731 template<typename Rec>
732 struct OperationStateT {
735 : m_parent(parent), m_file(file), m_receiver(di::move(receiver)) {}
736
737 void execute() override {
738 if (di::execution::get_stop_token(m_receiver).stop_requested()) {
739 di::execution::set_stopped(di::move(m_receiver));
740 } else {
741 auto open_mode_flags = [&] {
742 switch (m_file.get().mode()) {
744 return O_RDONLY;
746 return O_WRONLY | O_EXCL | O_CREAT;
748 return O_WRONLY | O_TRUNC | O_CREAT;
750 return O_RDWR;
752 return O_WRONLY | O_APPEND | O_CREAT;
753 default:
755 }
756 }();
757
758 // Enqueue io_uring sqe with the open request.
759 enqueue_io_operation(m_parent, this, [&](auto* sqe) {
760 sqe->opcode = IORING_OP_OPENAT;
761 sqe->fd = AT_FDCWD;
762 sqe->addr = reinterpret_cast<u64>(m_file.get().path().c_str());
763 sqe->len = m_file.get().create_mode();
764 sqe->open_flags = open_mode_flags;
765 });
766 }
767 }
768
769 void did_complete(io_uring::CQE const* cqe) override {
770 if (cqe->res < 0) {
771 di::execution::set_error(di::move(m_receiver), di::Error(PosixError(-cqe->res)));
772 } else {
773 m_file.get().set_fd(cqe->res);
774 di::execution::set_value(di::move(m_receiver), di::ref(m_file));
775 }
776 }
777
778 private:
780 enqueue_operation(self.m_parent, di::addressof(self));
781 }
782
783 IoUringContext* m_parent;
785 [[no_unique_address]] Rec m_receiver;
786 };
787 };
788
789 template<di::ReceiverOf<CompletionSignatures> Receiver>
790 using OperationState = di::meta::Type<OperationStateT<Receiver>>;
791
792 template<di::ReceiverOf<CompletionSignatures> Receiver>
793 friend auto tag_invoke(di::Tag<di::execution::connect>, OpenSender self, Receiver receiver) {
794 return OperationState<Receiver> { self.parent, self.file, di::move(receiver) };
795 }
796
797 constexpr friend auto tag_invoke(di::Tag<di::execution::get_env>, OpenSender const& self) {
798 return Env(self.parent);
799 }
800};
801
803public:
804 using is_sender = void;
805
807
810
813
814private:
815 template<typename Rec>
816 struct OperationStateT {
819 : m_parent(parent), m_socket(socket), m_receiver(di::move(receiver)) {}
820
821 void execute() override {
822 if (di::execution::get_stop_token(m_receiver).stop_requested()) {
823 di::execution::set_stopped(di::move(m_receiver));
824 } else {
825 // Enqueue io_uring sqe with the make socket request.
826 enqueue_io_operation(m_parent, this, [&](auto* sqe) {
827 sqe->opcode = IORING_OP_SOCKET;
828 sqe->fd = 1;
829 sqe->off = 1;
830 });
831 }
832 }
833
834 void did_complete(io_uring::CQE const* cqe) override {
835 if (cqe->res < 0) {
836 di::execution::set_error(di::move(m_receiver), di::Error(PosixError(-cqe->res)));
837 } else {
838 m_socket.get().set_fd(cqe->res);
839 di::execution::set_value(di::move(m_receiver), di::ref(m_socket));
840 }
841 }
842
843 private:
845 enqueue_operation(self.m_parent, di::addressof(self));
846 }
847
848 IoUringContext* m_parent;
850 [[no_unique_address]] Rec m_receiver;
851 };
852 };
853
854 template<di::ReceiverOf<CompletionSignatures> Receiver>
855 using OperationState = di::meta::Type<OperationStateT<Receiver>>;
856
857 template<di::ReceiverOf<CompletionSignatures> Receiver>
858 friend auto tag_invoke(di::Tag<di::execution::connect>, MakeSocketSender self, Receiver receiver) {
859 return OperationState<Receiver> { self.parent, self.socket, di::move(receiver) };
860 }
861
862 constexpr friend auto tag_invoke(di::Tag<di::execution::get_env>, MakeSocketSender const& self) {
863 return Env(self.parent);
864 }
865};
866
868public:
869 using is_sender = void;
870
872
875
878
879private:
880 template<typename Rec>
881 struct OperationStateT {
884 : m_parent(parent), m_socket(socket), m_receiver(di::move(receiver)) {}
885
886 void execute() override {
887 if (di::execution::get_stop_token(m_receiver).stop_requested()) {
888 di::execution::set_stopped(di::move(m_receiver));
889 } else {
890 // Enqueue io_uring sqe with the make socket request.
891 enqueue_io_operation(m_parent, this, [&](auto* sqe) {
892 sqe->opcode = IORING_OP_ACCEPT;
893 sqe->fd = m_socket.get().base_fd();
894 });
895 }
896 }
897
898 void did_complete(io_uring::CQE const* cqe) override {
899 if (cqe->res < 0) {
900 di::execution::set_error(di::move(m_receiver), di::Error(PosixError(-cqe->res)));
901 } else {
902 m_socket.get().set_fd(cqe->res);
903 di::execution::set_value(di::move(m_receiver), di::ref(m_socket));
904 }
905 }
906
907 private:
909 enqueue_operation(self.m_parent, di::addressof(self));
910 }
911
912 IoUringContext* m_parent;
914 [[no_unique_address]] Rec m_receiver;
915 };
916 };
917
918 template<di::ReceiverOf<CompletionSignatures> Receiver>
919 using OperationState = di::meta::Type<OperationStateT<Receiver>>;
920
921 template<di::ReceiverOf<CompletionSignatures> Receiver>
922 friend auto tag_invoke(di::Tag<di::execution::connect>, AcceptSender self, Receiver receiver) {
923 return OperationState<Receiver> { self.parent, self.socket, di::move(receiver) };
924 }
925
926 constexpr friend auto tag_invoke(di::Tag<di::execution::get_env>, AcceptSender const& self) {
927 return Env(self.parent);
928 }
929};
930
931template<typename Object, typename CreateSend>
932struct RunSender {
933public:
935
938
941
942private:
943 template<typename Rec>
944 struct OperationStateT {
946 struct Rec1 {
947 using is_receiver = void;
948
950
951 friend auto tag_invoke(di::Tag<di::execution::set_value>, Rec1&& self) { self.complete(); }
952 friend auto tag_invoke(di::Tag<di::execution::set_stopped>, Rec1&& self) { self.complete(); }
953 };
954
955 struct Rec2 : di::ReceiverAdaptor<Rec2> {
956 private:
957 using Base = di::ReceiverAdaptor<Rec2>;
958 friend Base;
959
960 public:
961 explicit Rec2(Rec* receiver) : m_receiver(receiver) {}
962
963 auto base() const& -> Rec const& { return *m_receiver; }
964 auto base() && -> Rec&& { return di::move(*m_receiver); }
965
966 private:
967 Rec* m_receiver;
968 };
969
970 explicit Type(IoUringContext* parent, di::ReferenceWrapper<Object> object, Rec&& receiver)
971 : m_parent(parent), m_object(object), m_receiver(di::move(receiver)) {}
972
973 private:
977
978 void finish_phase1() {
979 auto& op = m_op.template emplace<2>(di::DeferConstruct([&] {
980 return di::execution::connect(CloseSender(m_parent, m_object.get().fd()),
981 Rec2(di::addressof(m_receiver)));
982 }));
984 }
985
987 auto& op = self.m_op.template emplace<1>(di::DeferConstruct([&] {
989 di::execution::set_next(self.m_receiver, CreateSend(self.m_parent, self.m_object)),
990 Rec1([&self] {
991 return self.finish_phase1();
992 }));
993 }));
995 }
996
997 IoUringContext* m_parent;
999 [[no_unique_address]] Rec m_receiver;
1001 };
1002 };
1003
1004 template<typename Receiver>
1005 using OperationState = di::meta::Type<OperationStateT<Receiver>>;
1006
1007 template<
1009 friend auto tag_invoke(di::Tag<di::execution::subscribe>, RunSender self, Receiver receiver) {
1010 return OperationState<Receiver> { self.parent, self.object, di::move(receiver) };
1011 }
1012
1017};
1018
1020 return RunSender<AsyncFile, OpenSender> { self.parent(), self };
1021}
1022
1026
1030
1032 return { self.parent };
1033}
1034
1036 u16 create_mode) {
1037 return di::make_deferred<AsyncFile>(self.parent, di::move(path), mode, create_mode);
1038}
1039
1041 return di::make_deferred<AsyncFile>(self.parent, di::move(path), mode, 0666);
1042}
1043
1047
1051
1052template<di::concepts::Invocable<io_uring::SQE*> Fun>
1053inline void enqueue_io_operation(IoUringContext* context, OperationStateBase* op, Fun&& function) {
1054 auto sqe = context->m_handle.get_next_sqe();
1055 ASSERT(sqe);
1056 di::fill_n(reinterpret_cast<di::Byte*>(sqe.data()), sizeof(sqe), 0_b);
1057 di::invoke(di::forward<Fun>(function), sqe.data());
1058 sqe->user_data = reinterpret_cast<uintptr_t>(op);
1059}
1060
1062 context->m_queue.push(*op);
1063}
1064
1066 return context->get_scheduler();
1067}
1068
1070 return IoUringScheduler(this);
1071}
1072}
#define ASSERT
Definition assert_bool.h:16
Definition forward_list_node.h:9
Definition queue.h:23
Definition function.h:365
Definition atomic.h:15
Definition defer_construct.h:8
Definition reference_wrapper.h:14
Definition optional_forward_declaration.h:5
Definition span_forward_declaration.h:10
Definition variant_forward_declaration.h:6
AcceptSocket(int base_fd)
Definition io_uring_context.h:662
auto base_fd() const -> int
Definition io_uring_context.h:664
Definition io_uring_context.h:629
auto mode() const -> OpenMode
Definition io_uring_context.h:636
friend auto tag_invoke(di::Tag< di::execution::async_read_some >, AsyncFile &self, di::Span< di::Byte > buffer, di::Optional< u64 > offset)
Definition io_uring_context.h:643
friend auto tag_invoke(di::Tag< di::execution::async_write_some >, AsyncFile &self, di::Span< di::Byte const > buffer, di::Optional< u64 > offset)
Definition io_uring_context.h:648
auto path() const -> di::Path const &
Definition io_uring_context.h:635
auto create_mode() const -> u16
Definition io_uring_context.h:637
auto parent() const -> IoUringContext *
Definition io_uring_context.h:634
auto fd() const -> int
Definition io_uring_context.h:639
AsyncFile(IoUringContext *parent, di::Path path, OpenMode mode, u16 create_mode)
Definition io_uring_context.h:631
void set_fd(int fd)
Definition io_uring_context.h:640
Definition io_uring_context.h:673
void set_fd(int fd)
Definition io_uring_context.h:683
AsyncSocket(IoUringContext *context, Args &&... args)
Definition io_uring_context.h:677
friend auto tag_invoke(di::Tag< di::execution::async_accept >, AsyncSocket &self)
Definition io_uring_context.h:712
friend auto tag_invoke(di::Tag< di::execution::async_write_some >, AsyncSocket &self, di::Span< di::Byte const > buffer, di::Optional< u64 >)
Definition io_uring_context.h:691
friend auto tag_invoke(di::Tag< di::execution::async_connect >, AsyncSocket &self, net::UnixAddress address)
Definition io_uring_context.h:700
friend auto tag_invoke(di::Tag< di::execution::async_bind >, AsyncSocket &self, net::UnixAddress address)
Definition io_uring_context.h:696
friend auto tag_invoke(di::Tag< di::execution::async_read_some >, AsyncSocket &self, di::Span< di::Byte > buffer, di::Optional< u64 >)
Definition io_uring_context.h:686
friend auto tag_invoke(di::Tag< di::execution::async_listen >, AsyncSocket &self, int count)
Definition io_uring_context.h:704
auto fd() const -> int
Definition io_uring_context.h:682
friend auto tag_invoke(di::Tag< di::execution::async_shutdown >, AsyncSocket &self, net::Shutdown how)
Definition io_uring_context.h:708
auto parent() const -> IoUringContext *
Definition io_uring_context.h:680
Definition io_uring.h:19
auto get_next_sqe() -> di::Optional< SQE & >
Definition io_uring.cpp:21
static auto create() -> di::Result< IoUringHandle >
Definition io_uring.cpp:61
Definition address.h:8
#define DI_IMMOVABLE_NO_UNIQUE_ADDRESS
Definition compiler.h:15
Definition operations.h:11
#define O_WRONLY
Definition fcntl.h:8
#define O_CREAT
Definition fcntl.h:10
#define O_RDONLY
Definition fcntl.h:7
#define O_EXCL
Definition fcntl.h:11
#define O_RDWR
Definition fcntl.h:9
#define O_TRUNC
Definition fcntl.h:12
#define TRY
Definition monad_try.h:23
PathImpl< TransparentString > Path
Definition path.h:10
meta::Type< OperationStateT< Send, Shape, Function, Rec > > OperationState
Definition bulk.h:102
constexpr auto set_error
Definition set_error.h:14
constexpr auto set_next
Set the next sender of a sequence.
Definition sequence_sender.h:77
constexpr auto start
Definition start.h:20
constexpr auto make_env
Create an environment with overrides for queries.
Definition make_env.h:147
meta::Type< receiver_interface_ns::ReceiverAdaptor< Self, Base > > ReceiverAdaptor
Definition receiver_adaptor.h:236
constexpr auto set_stopped
Definition set_stopped.h:14
constexpr auto get_sequence_cardinality
A query that returns the cardinality of a sequence.
Definition get_sequence_cardinality.h:45
constexpr auto with
Specify an override for an environment query.
Definition make_env.h:112
constexpr auto get_stop_token
Definition get_stop_token.h:25
constexpr auto connect
Definition connect.h:42
constexpr auto set_value
Definition set_value.h:14
T::Type Type
Definition core.h:26
decltype(execution::set_next(util::declval< meta::RemoveCVRef< Rec > & >(), util::declval< Send >())) NextSenderOf
Definition sequence_sender.h:82
decltype(execution::connect(util::declval< Send >(), util::declval< Rec >())) ConnectResult
Definition connect_result.h:7
std::byte Byte
Definition byte.h:63
__UINT64_TYPE__ u64
Definition integers.h:12
__UINT32_TYPE__ u32
Definition integers.h:11
di::meta::Decay< decltype(T)> Tag
Definition tag_invoke.h:28
__UINT16_TYPE__ u16
Definition integers.h:10
Expected< T, Error > Result
Definition result.h:8
StatusCode< Erased< long > > Error
Definition error.h:8
Definition zstring_parser.h:9
constexpr auto make_deferred
Creates a deferred function object.
Definition make_deferred.h:75
constexpr auto ref
Definition reference_wrapper.h:98
constexpr auto invoke
Definition invoke.h:100
constexpr auto c_
A value of type Constexpr<val>.
Definition constexpr.h:252
constexpr auto fill_n
Definition fill_n.h:21
constexpr auto count
Definition count.h:37
constexpr auto copy
Definition copy.h:30
void unreachable()
Definition unreachable.h:4
struct io_uring_cqe CQE
Definition io_uring.h:11
Definition io_uring.h:8
void enqueue_operation(IoUringContext *, OperationStateBase *)
Definition io_uring_context.h:1061
auto get_scheduler(IoUringContext *) -> IoUringScheduler
Definition io_uring_context.h:1065
auto tag_invoke(di::Tag< di::execution::run >, AsyncFile &self)
Definition io_uring_context.h:1019
Shutdown
Definition socket.h:4
PosixError
Definition error.h:7
auto system_call(Number number) -> di::Expected< R, di::BasicError >
Definition system_call.h:27
OpenMode
Definition sync_file.h:109
@ Readonly
Definition sync_file.h:109
@ WriteNew
Definition sync_file.h:109
@ AppendOnly
Definition sync_file.h:109
@ ReadWrite
Definition sync_file.h:109
@ WriteClobber
Definition sync_file.h:109
Defines the sequence sender concepts and related CPOs.
__UINTPTR_TYPE__ uintptr_t
Definition stdint.h:42
Definition get_completion_scheduler.h:10
Definition sequence_sender.h:86
Definition set_error.h:6
Definition set_stopped.h:6
Definition set_value.h:6
Definition completion_signuatures.h:7
Definition immovable.h:4
Type(IoUringContext *parent, di::ReferenceWrapper< AsyncSocket > socket, Rec &&receiver)
Definition io_uring_context.h:883
void did_complete(io_uring::CQE const *cqe) override
Definition io_uring_context.h:898
void execute() override
Definition io_uring_context.h:886
friend void tag_invoke(di::Tag< di::execution::start >, Type &self)
Definition io_uring_context.h:908
Definition io_uring_context.h:867
linux::AsyncSocket< AcceptSocket > AsyncSocket
Definition io_uring_context.h:871
constexpr friend auto tag_invoke(di::Tag< di::execution::get_env >, AcceptSender const &self)
Definition io_uring_context.h:926
di::ReferenceWrapper< AsyncSocket > socket
Definition io_uring_context.h:877
void is_sender
Definition io_uring_context.h:869
di::CompletionSignatures< di::SetValue(di::ReferenceWrapper< AsyncSocket >), di::SetError(di::Error), di::SetStopped()> CompletionSignatures
Definition io_uring_context.h:873
IoUringContext * parent
Definition io_uring_context.h:876
friend auto tag_invoke(di::Tag< di::execution::connect >, AcceptSender self, Receiver receiver)
Definition io_uring_context.h:922
void execute() override
Definition io_uring_context.h:414
Type(IoUringContext *parent, int file_descriptor, net::UnixAddress address, Rec receiver)
Definition io_uring_context.h:404
friend void tag_invoke(di::Tag< di::execution::start >, Type &self)
Definition io_uring_context.h:436
Definition io_uring_context.h:390
int file_descriptor
Definition io_uring_context.h:397
constexpr friend auto tag_invoke(di::Tag< di::execution::get_env >, BindSender const &self)
Definition io_uring_context.h:456
di::CompletionSignatures< di::SetValue(), di::SetError(di::Error), di::SetStopped()> CompletionSignatures
Definition io_uring_context.h:394
void is_sender
Definition io_uring_context.h:392
friend auto tag_invoke(di::Tag< di::execution::connect >, BindSender self, Receiver receiver)
Definition io_uring_context.h:451
IoUringContext * parent
Definition io_uring_context.h:396
net::UnixAddress address
Definition io_uring_context.h:398
Type(IoUringContext *parent, int file_descriptor, Rec receiver)
Definition io_uring_context.h:265
void did_complete(io_uring::CQE const *cqe) override
Definition io_uring_context.h:280
void execute() override
Definition io_uring_context.h:268
friend void tag_invoke(di::Tag< di::execution::start >, Type &self)
Definition io_uring_context.h:289
Definition io_uring_context.h:252
void is_sender
Definition io_uring_context.h:254
constexpr friend auto tag_invoke(di::Tag< di::execution::get_env >, CloseSender const &self)
Definition io_uring_context.h:307
int file_descriptor
Definition io_uring_context.h:259
friend auto tag_invoke(di::Tag< di::execution::connect >, CloseSender self, Receiver receiver)
Definition io_uring_context.h:303
di::CompletionSignatures< di::SetValue(), di::SetError(di::Error), di::SetStopped()> CompletionSignatures
Definition io_uring_context.h:256
IoUringContext * parent
Definition io_uring_context.h:258
void execute() override
Definition io_uring_context.h:336
Type(IoUringContext *parent, int file_descriptor, net::UnixAddress address, Rec receiver)
Definition io_uring_context.h:326
void did_complete(io_uring::CQE const *cqe) override
Definition io_uring_context.h:356
friend void tag_invoke(di::Tag< di::execution::start >, Type &self)
Definition io_uring_context.h:365
Definition io_uring_context.h:312
di::CompletionSignatures< di::SetValue(), di::SetError(di::Error), di::SetStopped()> CompletionSignatures
Definition io_uring_context.h:316
int file_descriptor
Definition io_uring_context.h:319
void is_sender
Definition io_uring_context.h:314
IoUringContext * parent
Definition io_uring_context.h:318
constexpr friend auto tag_invoke(di::Tag< di::execution::get_env >, ConnectSender const &self)
Definition io_uring_context.h:385
friend auto tag_invoke(di::Tag< di::execution::connect >, ConnectSender self, Receiver receiver)
Definition io_uring_context.h:380
net::UnixAddress address
Definition io_uring_context.h:320
Definition io_uring_context.h:95
constexpr friend auto tag_invoke(di::execution::GetCompletionScheduler< CPO >, Env const &self)
Definition io_uring_context.h:99
IoUringContext * parent
Definition io_uring_context.h:96
Definition io_uring_context.h:63
void run()
Definition io_uring_context.cpp:6
di::Queue< OperationStateBase, di::IntrusiveForwardList< OperationStateBase > > m_queue
Definition io_uring_context.h:81
void finish()
Definition io_uring_context.h:74
di::Atomic< bool > m_done
Definition io_uring_context.h:82
static auto create() -> di::Result< IoUringContext >
Definition io_uring_context.h:1048
io_uring::IoUringHandle m_handle
Definition io_uring_context.h:80
IoUringContext(IoUringContext &&other)
Definition io_uring_context.h:67
auto get_scheduler() -> IoUringScheduler
Definition io_uring_context.h:1069
Definition io_uring_context.h:85
friend auto tag_invoke(di::Tag< di::execution::schedule >, IoUringScheduler const &self) -> ScheduleSender
Definition io_uring_context.h:1031
IoUringContext * parent
Definition io_uring_context.h:87
constexpr friend auto operator==(IoUringScheduler const &, IoUringScheduler const &) -> bool=default
void execute() override
Definition io_uring_context.h:481
Type(IoUringContext *parent, int file_descriptor, int count, Rec receiver)
Definition io_uring_context.h:475
friend void tag_invoke(di::Tag< di::execution::start >, Type &self)
Definition io_uring_context.h:496
Definition io_uring_context.h:461
void is_sender
Definition io_uring_context.h:463
IoUringContext * parent
Definition io_uring_context.h:467
constexpr friend auto tag_invoke(di::Tag< di::execution::get_env >, ListenSender const &self)
Definition io_uring_context.h:515
int file_descriptor
Definition io_uring_context.h:468
int count
Definition io_uring_context.h:469
di::CompletionSignatures< di::SetValue(), di::SetError(di::Error), di::SetStopped()> CompletionSignatures
Definition io_uring_context.h:465
friend auto tag_invoke(di::Tag< di::execution::connect >, ListenSender self, Receiver receiver)
Definition io_uring_context.h:511
void did_complete(io_uring::CQE const *cqe) override
Definition io_uring_context.h:834
void execute() override
Definition io_uring_context.h:821
Type(IoUringContext *parent, di::ReferenceWrapper< AsyncSocket > socket, Rec &&receiver)
Definition io_uring_context.h:818
friend void tag_invoke(di::Tag< di::execution::start >, Type &self)
Definition io_uring_context.h:844
Definition io_uring_context.h:802
di::ReferenceWrapper< AsyncSocket > socket
Definition io_uring_context.h:812
constexpr friend auto tag_invoke(di::Tag< di::execution::get_env >, MakeSocketSender const &self)
Definition io_uring_context.h:862
friend auto tag_invoke(di::Tag< di::execution::connect >, MakeSocketSender self, Receiver receiver)
Definition io_uring_context.h:858
linux::AsyncSocket< di::Void > AsyncSocket
Definition io_uring_context.h:806
void is_sender
Definition io_uring_context.h:804
IoUringContext * parent
Definition io_uring_context.h:811
di::CompletionSignatures< di::SetValue(di::ReferenceWrapper< AsyncSocket >), di::SetError(di::Error), di::SetStopped()> CompletionSignatures
Definition io_uring_context.h:808
void did_complete(io_uring::CQE const *cqe) override
Definition io_uring_context.h:769
Type(IoUringContext *parent, di::ReferenceWrapper< AsyncFile > file, Rec &&receiver)
Definition io_uring_context.h:734
void execute() override
Definition io_uring_context.h:737
friend void tag_invoke(di::Tag< di::execution::start >, Type &self)
Definition io_uring_context.h:779
Definition io_uring_context.h:720
friend auto tag_invoke(di::Tag< di::execution::connect >, OpenSender self, Receiver receiver)
Definition io_uring_context.h:793
di::CompletionSignatures< di::SetValue(di::ReferenceWrapper< AsyncFile >), di::SetError(di::Error), di::SetStopped()> CompletionSignatures
Definition io_uring_context.h:724
di::ReferenceWrapper< AsyncFile > file
Definition io_uring_context.h:728
void is_sender
Definition io_uring_context.h:722
IoUringContext * parent
Definition io_uring_context.h:727
constexpr friend auto tag_invoke(di::Tag< di::execution::get_env >, OpenSender const &self)
Definition io_uring_context.h:797
Definition io_uring_context.h:57
virtual void did_complete(io_uring::CQE const *)
Definition io_uring_context.h:60
void did_complete(io_uring::CQE const *cqe) override
Definition io_uring_context.h:143
void execute() override
Definition io_uring_context.h:128
Type(IoUringContext *parent, int file_descriptor, di::Span< di::Byte > buffer, di::Optional< u64 > offset, Rec receiver)
Definition io_uring_context.h:120
friend void tag_invoke(di::Tag< di::execution::start >, Type &self)
Definition io_uring_context.h:152
Definition io_uring_context.h:104
void is_sender
Definition io_uring_context.h:106
friend auto tag_invoke(di::Tag< di::execution::connect >, ReadSomeSender self, Receiver receiver)
Definition io_uring_context.h:168
int file_descriptor
Definition io_uring_context.h:112
constexpr friend auto tag_invoke(di::Tag< di::execution::get_env >, ReadSomeSender const &self)
Definition io_uring_context.h:173
di::Span< di::Byte > buffer
Definition io_uring_context.h:113
IoUringContext * parent
Definition io_uring_context.h:111
di::Optional< u64 > offset
Definition io_uring_context.h:114
di::CompletionSignatures< di::SetValue(size_t), di::SetError(di::Error), di::SetStopped()> CompletionSignatures
Definition io_uring_context.h:108
friend auto tag_invoke(di::Tag< di::execution::set_value >, Rec1 &&self)
Definition io_uring_context.h:951
void is_receiver
Definition io_uring_context.h:947
friend auto tag_invoke(di::Tag< di::execution::set_stopped >, Rec1 &&self)
Definition io_uring_context.h:952
di::Function< void()> complete
Definition io_uring_context.h:949
auto base() const &-> Rec const &
Definition io_uring_context.h:963
Rec2(Rec *receiver)
Definition io_uring_context.h:961
auto base() &&-> Rec &&
Definition io_uring_context.h:964
Type(IoUringContext *parent, di::ReferenceWrapper< Object > object, Rec &&receiver)
Definition io_uring_context.h:970
friend void tag_invoke(di::Tag< di::execution::start >, Type &self)
Definition io_uring_context.h:986
Definition io_uring_context.h:932
di::SequenceTag is_sender
Definition io_uring_context.h:934
di::CompletionSignatures< di::SetValue(di::ReferenceWrapper< Object >), di::SetError(di::Error), di::SetStopped()> CompletionSignatures
Definition io_uring_context.h:936
friend auto tag_invoke(di::Tag< di::execution::subscribe >, RunSender self, Receiver receiver)
Definition io_uring_context.h:1009
constexpr friend auto tag_invoke(di::Tag< di::execution::get_env >, RunSender const &self)
Definition io_uring_context.h:1013
IoUringContext * parent
Definition io_uring_context.h:939
di::ReferenceWrapper< Object > object
Definition io_uring_context.h:940
void execute() override
Definition io_uring_context.h:598
Type(IoUringContext *parent, Rec &&receiver)
Definition io_uring_context.h:596
friend void tag_invoke(di::Tag< di::execution::start >, Type &self)
Definition io_uring_context.h:607
Definition io_uring_context.h:583
friend auto tag_invoke(di::Tag< di::execution::connect >, ScheduleSender self, Rec receiver)
Definition io_uring_context.h:620
IoUringContext * parent
Definition io_uring_context.h:589
constexpr friend auto tag_invoke(di::Tag< di::execution::get_env >, ScheduleSender const &self)
Definition io_uring_context.h:624
void is_sender
Definition io_uring_context.h:585
di::CompletionSignatures< di::SetValue(), di::SetStopped()> CompletionSignatures
Definition io_uring_context.h:587
void execute() override
Definition io_uring_context.h:537
Type(IoUringContext *parent, int file_descriptor, net::Shutdown how, Rec receiver)
Definition io_uring_context.h:534
void did_complete(io_uring::CQE const *cqe) override
Definition io_uring_context.h:550
friend void tag_invoke(di::Tag< di::execution::start >, Type &self)
Definition io_uring_context.h:559
Definition io_uring_context.h:520
constexpr friend auto tag_invoke(di::Tag< di::execution::get_env >, ShutdownSender const &self)
Definition io_uring_context.h:578
int file_descriptor
Definition io_uring_context.h:527
IoUringContext * parent
Definition io_uring_context.h:526
void is_sender
Definition io_uring_context.h:522
di::CompletionSignatures< di::SetValue(), di::SetError(di::Error), di::SetStopped()> CompletionSignatures
Definition io_uring_context.h:524
friend auto tag_invoke(di::Tag< di::execution::connect >, ShutdownSender self, Receiver receiver)
Definition io_uring_context.h:574
net::Shutdown how
Definition io_uring_context.h:528
void did_complete(io_uring::CQE const *cqe) override
Definition io_uring_context.h:217
void execute() override
Definition io_uring_context.h:202
Type(IoUringContext *parent, int file_descriptor, di::Span< di::Byte const > buffer, di::Optional< u64 > offset, Rec receiver)
Definition io_uring_context.h:194
friend void tag_invoke(di::Tag< di::execution::start >, Type &self)
Definition io_uring_context.h:226
Definition io_uring_context.h:178
di::Span< di::Byte const > buffer
Definition io_uring_context.h:187
di::Optional< u64 > offset
Definition io_uring_context.h:188
int file_descriptor
Definition io_uring_context.h:186
void is_sender
Definition io_uring_context.h:180
friend auto tag_invoke(di::Tag< di::execution::connect >, WriteSomeSender self, Receiver receiver)
Definition io_uring_context.h:242
constexpr friend auto tag_invoke(di::Tag< di::execution::get_env >, WriteSomeSender const &self)
Definition io_uring_context.h:247
IoUringContext * parent
Definition io_uring_context.h:185
di::CompletionSignatures< di::SetValue(size_t), di::SetError(di::Error), di::SetStopped()> CompletionSignatures
Definition io_uring_context.h:182