YACLib
C++ library for concurrent tasks execution
Loading...
Searching...
No Matches
await_on_awaiter.hpp
Go to the documentation of this file.
1#pragma once
2
11
12namespace yaclib::detail {
13
14template <bool Single>
16 std::conditional_t<Single, OneCounter<NopeBase, NopeDeleter>, AtomicCounter<NopeBase, NopeDeleter>>;
17
18template <bool Single>
19class AwaitOnEvent : public InlineCore, public AwaitOnCounterT<Single> {
20 public:
21 static constexpr auto kShared = false;
22
24 return *this;
25 }
26
27 explicit AwaitOnEvent(std::size_t n) noexcept : AwaitOnCounterT<Single>{n} {
28 }
29
30 [[nodiscard]] InlineCore* Here(InlineCore& caller) noexcept final {
31 return Impl<false>(caller);
32 }
33
34#if YACLIB_SYMMETRIC_TRANSFER != 0
35 [[nodiscard]] yaclib_std::coroutine_handle<> Next(InlineCore& caller) noexcept final {
36 return Impl<true>(caller);
37 }
38#endif
39
40 protected:
41 BaseCore* job{nullptr};
42
43 private:
44 template <bool SymmetricTransfer>
45 [[nodiscard]] YACLIB_INLINE auto Impl(InlineCore& /*caller*/) noexcept {
46 if constexpr (Single) {
48 } else {
49 if (this->SubEqual(1)) {
50 YACLIB_ASSERT(job != nullptr);
52 }
53 }
55 }
56};
57
58template <typename Handle>
60 explicit AwaitOnAwaiter(IExecutor& e, Handle caller) noexcept : AwaitOnEvent<false>{1}, _executor{e} {
61 job = &caller.core;
62 }
63
64 constexpr bool await_ready() const noexcept {
65 return false;
66 }
67
68 template <typename Promise>
69 YACLIB_INLINE void await_suspend(yaclib_std::coroutine_handle<Promise> handle) noexcept {
70 auto& core = handle.promise();
71 core._executor = &_executor;
72 Handle caller_handle{*job};
73 job = &core;
74
75 if (!caller_handle.SetCallback(*this)) {
76 _executor.Submit(core);
77 }
78 }
79
80 constexpr void await_resume() const noexcept {
81 }
82
83 private:
84 IExecutor& _executor;
85};
86
87template <typename Event>
89 public:
90 static constexpr auto kShared = Event::kShared;
91
92 template <typename... Handles>
93 explicit MultiAwaitOnAwaiter(IExecutor& e, Handles... handles) noexcept
94 : Event{sizeof...(handles) + 1}, _executor{e} {
95 SetCallbacksStatic(*this, handles...);
96 }
97
98 template <typename It>
99 explicit MultiAwaitOnAwaiter(IExecutor& e, It it, std::size_t count) noexcept : Event{count + 1}, _executor{e} {
100 SetCallbacksDynamic(*this, it, count);
101 }
102
103 constexpr bool await_ready() const noexcept {
104 return false;
105 }
106
107 template <typename Promise>
108 YACLIB_INLINE void await_suspend(yaclib_std::coroutine_handle<Promise> handle) noexcept {
109 auto& core = handle.promise();
110 core._executor = &_executor;
111 this->job = &core;
112
113 if (this->SubEqual(1)) {
114 _executor.Submit(core);
115 }
116 }
117
118 constexpr void await_resume() const noexcept {
119 }
120
121 private:
122 IExecutor& _executor;
123};
124
125} // namespace yaclib::detail
virtual void Submit(Job &job) noexcept=0
Submit given job.
AwaitOnEvent(std::size_t n) noexcept
InlineCore * Here(InlineCore &caller) noexcept final
AwaitOnEvent & GetCall() noexcept
static constexpr auto kShared
constexpr void await_resume() const noexcept
YACLIB_INLINE void await_suspend(yaclib_std::coroutine_handle< Promise > handle) noexcept
MultiAwaitOnAwaiter(IExecutor &e, Handles... handles) noexcept
constexpr bool await_ready() const noexcept
MultiAwaitOnAwaiter(IExecutor &e, It it, std::size_t count) noexcept
#define YACLIB_ASSERT(cond)
Definition log.hpp:85
std::conditional_t< Single, OneCounter< NopeBase, NopeDeleter >, AtomicCounter< NopeBase, NopeDeleter > > AwaitOnCounterT
Contract< V, E > MakeContract()
Creates related future and promise.
Definition contract.hpp:25
constexpr void await_resume() const noexcept
YACLIB_INLINE void await_suspend(yaclib_std::coroutine_handle< Promise > handle) noexcept
constexpr bool await_ready() const noexcept
AwaitOnAwaiter(IExecutor &e, Handle caller) noexcept