1818#include < boost/capy/task.hpp>
1919#include < boost/capy/concept/io_awaitable.hpp>
2020#include < boost/capy/concept/executor.hpp>
21- #include < boost/capy/ex/any_executor_ref .hpp>
21+ #include < boost/capy/ex/any_executor .hpp>
2222#include < boost/capy/ex/get_stop_token.hpp>
2323#include < boost/capy/ex/run_async.hpp>
2424
@@ -44,16 +44,33 @@ class BOOST_COROSIO_DECL
4444 struct waiter ;
4545
4646 io_context& ctx_;
47- capy::any_executor_ref dispatch_;
48- capy::any_executor_ref post_;
47+ capy::any_executor ex_;
4948 waiter* waiters_ = nullptr ;
5049 std::vector<acceptor> ports_;
5150
51+ template <capy::Executor Ex>
5252 struct launch_wrapper
5353 {
5454 struct promise_type
5555 {
56- capy::any_executor_ref d;
56+ Ex ex; // Stored directly in frame, no allocation
57+
58+ // For regular coroutines: first arg is the executor
59+ template <class E , class ... Args>
60+ requires capy::Executor<std::decay_t <E>>
61+ promise_type (E e, Args&&...)
62+ : ex(std::move(e))
63+ {
64+ }
65+
66+ // For lambda coroutines: first arg is lambda closure, second is executor
67+ template <class Closure , class E , class ... Args>
68+ requires (!capy::Executor<std::decay_t <Closure>> &&
69+ capy::Executor<std::decay_t <E>>)
70+ promise_type (Closure&&, E e, Args&&...)
71+ : ex(std::move(e))
72+ {
73+ }
5774
5875 launch_wrapper get_return_object () noexcept {
5976 return {std::coroutine_handle<promise_type>::from_promise (*this )};
@@ -70,21 +87,18 @@ class BOOST_COROSIO_DECL
7087 struct adapter
7188 {
7289 std::decay_t <Awaitable> aw;
73- capy::any_executor_ref d ;
90+ Ex* ex_ptr ;
7491
7592 bool await_ready () { return aw.await_ready (); }
7693 auto await_resume () { return aw.await_resume (); }
7794
7895 auto await_suspend (std::coroutine_handle<promise_type> h)
7996 {
80- if constexpr (capy::IoAwaitable<
81- std::decay_t <Awaitable>, capy::any_executor_ref>)
82- return aw.await_suspend (h, d, std::stop_token{});
83- else
84- return aw.await_suspend (h);
97+ static_assert (capy::IoAwaitable<std::decay_t <Awaitable>, Ex>);
98+ return aw.await_suspend (h, *ex_ptr, std::stop_token{});
8599 }
86100 };
87- return adapter{std::forward<Awaitable>(a), d };
101+ return adapter{std::forward<Awaitable>(a), &ex };
88102 }
89103 };
90104
@@ -126,8 +140,18 @@ class BOOST_COROSIO_DECL
126140 public:
127141 push_aw (tcp_server& self, worker_base& w) noexcept ;
128142 bool await_ready () const noexcept ;
129- std::coroutine_handle<> await_suspend (std::coroutine_handle<> h) noexcept ;
143+
144+ template <class Handle , class Ex >
145+ std::coroutine_handle<> await_suspend (
146+ Handle h, Ex&, std::stop_token) noexcept
147+ {
148+ return await_suspend_impl (h);
149+ }
150+
130151 void await_resume () noexcept ;
152+
153+ private:
154+ std::coroutine_handle<> await_suspend_impl (std::coroutine_handle<> h) noexcept ;
131155 };
132156
133157 class BOOST_COROSIO_DECL pop_aw
@@ -138,8 +162,17 @@ class BOOST_COROSIO_DECL
138162 public:
139163 pop_aw (tcp_server& self) noexcept ;
140164 bool await_ready () const noexcept ;
141- bool await_suspend (std::coroutine_handle<> h) noexcept ;
165+
166+ template <class Handle , class Ex >
167+ bool await_suspend (Handle h, Ex&, std::stop_token) noexcept
168+ {
169+ return await_suspend_impl (h);
170+ }
171+
142172 system::result<worker_base&> await_resume () noexcept ;
173+
174+ private:
175+ bool await_suspend_impl (std::coroutine_handle<> h) noexcept ;
143176 };
144177
145178 push_aw push (worker_base& w);
@@ -159,17 +192,9 @@ class BOOST_COROSIO_DECL
159192 friend class workers ;
160193
161194 public:
162- socket sock;
163-
164195 virtual ~worker_base () = default ;
165196 virtual void run (launcher launch) = 0;
166197 virtual corosio::socket& socket () = 0;
167-
168- protected:
169- worker_base (capy::execution_context& ctx)
170- : sock(ctx)
171- {
172- }
173198 };
174199
175200 class launcher
@@ -217,14 +242,15 @@ class BOOST_COROSIO_DECL
217242 } guard{srv_, w};
218243
219244 auto wrapper =
220- [](Executor ex, tcp_server* self, capy::task<void > t, worker_base* wp)
221- -> launch_wrapper
222- {
223- (void )ex; // Prevent executor destruction while coroutine runs
224- co_await std::move (t);
225- co_await self->push (*wp);
226- }(ex, srv_, std::move (task), w);
245+ [](Executor ex, tcp_server* self, capy::task<void > t, worker_base* wp)
246+ -> launch_wrapper<Executor>
247+ {
248+ (void )ex; // Executor stored in promise via constructor
249+ co_await std::move (t);
250+ co_await self->push (*wp);
251+ }(ex, srv_, std::move (task), w);
227252
253+ // Executor is now stored in promise via constructor
228254 ex.post (std::exchange (wrapper.h , nullptr )); // Release before post
229255 guard.w = nullptr ; // Success - dismiss guard
230256 }
@@ -274,8 +300,7 @@ class BOOST_COROSIO_DECL
274300 io_context& ctx,
275301 Ex const & ex)
276302 : ctx_(ctx)
277- , dispatch_(ex)
278- , post_(ex)
303+ , ex_(ex)
279304 {
280305 }
281306
0 commit comments