| 78 | |
| 79 | template <typename T, typename Executor, typename F, typename Handler> |
| 80 | awaitable<awaitable_thread_entry_point, Executor> co_spawn_entry_point( |
| 81 | awaitable<T, Executor>*, Executor ex, F f, Handler handler) |
| 82 | { |
| 83 | auto spawn_work = make_co_spawn_work_guard(ex); |
| 84 | auto handler_work = make_co_spawn_work_guard( |
| 85 | asio::get_associated_executor(handler, ex)); |
| 86 | |
| 87 | (void) co_await (dispatch)( |
| 88 | use_awaitable_t<Executor>{__FILE__, __LINE__, "co_spawn_entry_point"}); |
| 89 | |
| 90 | (co_await awaitable_thread_has_context_switched{}) = false; |
| 91 | std::exception_ptr e = nullptr; |
| 92 | bool done = false; |
| 93 | try |
| 94 | { |
| 95 | T t = co_await f(); |
| 96 | |
| 97 | done = true; |
| 98 | |
| 99 | if (co_await awaitable_thread_has_context_switched{}) |
| 100 | { |
| 101 | (dispatch)(handler_work.get_executor(), |
| 102 | [handler = std::move(handler), t = std::move(t)]() mutable |
| 103 | { |
| 104 | std::move(handler)(std::exception_ptr(), std::move(t)); |
| 105 | }); |
| 106 | } |
| 107 | else |
| 108 | { |
| 109 | (post)(handler_work.get_executor(), |
| 110 | [handler = std::move(handler), t = std::move(t)]() mutable |
| 111 | { |
| 112 | std::move(handler)(std::exception_ptr(), std::move(t)); |
| 113 | }); |
| 114 | } |
| 115 | |
| 116 | co_return; |
| 117 | } |
| 118 | catch (...) |
| 119 | { |
| 120 | if (done) |
| 121 | throw; |
| 122 | |
| 123 | e = std::current_exception(); |
| 124 | } |
| 125 | |
| 126 | if (co_await awaitable_thread_has_context_switched{}) |
| 127 | { |
| 128 | (dispatch)(handler_work.get_executor(), |
| 129 | [handler = std::move(handler), e]() mutable |
| 130 | { |
| 131 | std::move(handler)(e, T()); |
| 132 | }); |
| 133 | } |
| 134 | else |
| 135 | { |
| 136 | (post)(handler_work.get_executor(), |
| 137 | [handler = std::move(handler), e]() mutable |
nothing calls this directly
no test coverage detected