Skip to content

Commit 5d16efd

Browse files
committed
dispatch returns void and resumes inline if possible
1 parent 3980e97 commit 5d16efd

10 files changed

Lines changed: 23 additions & 37 deletions

File tree

‎include/boost/corosio/basic_io_context.hpp‎

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -342,21 +342,18 @@ class basic_io_context::executor_type
342342
/** Dispatch a coroutine handle.
343343
344344
This is the executor interface for capy coroutines. If called
345-
from within `run()`, returns the handle for symmetric transfer.
346-
Otherwise posts the handle and returns `noop_coroutine`.
345+
from within `run()`, resumes the coroutine inline via a normal
346+
function call. Otherwise posts the coroutine for later execution.
347347
348348
@param h The coroutine handle to dispatch.
349-
350-
@return The handle for symmetric transfer, or `noop_coroutine`
351-
if the handle was posted.
352349
*/
353-
capy::coro
350+
void
354351
dispatch(capy::coro h) const
355352
{
356353
if (running_in_this_thread())
357-
return h;
358-
ctx_->sched_->post(h);
359-
return std::noop_coroutine();
354+
h.resume();
355+
else
356+
ctx_->sched_->post(h);
360357
}
361358

362359
/** Post a coroutine for deferred execution.

‎include/boost/corosio/tcp_server.hpp‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,8 @@ class BOOST_COROSIO_DECL
354354
Ex const&, std::stop_token) noexcept
355355
{
356356
// Dispatch to server's executor before touching shared state
357-
return self_.ex_.dispatch(h);
357+
self_.ex_.dispatch(h);
358+
return std::noop_coroutine();
358359
}
359360

360361
void await_resume() noexcept

‎src/corosio/src/detail/epoll/acceptors.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ operator()()
128128
capy::executor_ref saved_ex( std::move( ex ) );
129129
capy::coro saved_h( std::move( h ) );
130130
auto prevent_premature_destruction = std::move(impl_ptr);
131-
saved_ex.dispatch( saved_h ).resume();
131+
saved_ex.dispatch( saved_h );
132132
}
133133

134134
epoll_acceptor_impl::

‎src/corosio/src/detail/iocp/overlapped_op.hpp‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -148,13 +148,13 @@ struct overlapped_op
148148
dwError = err;
149149
}
150150

151-
/** Complete immediately and return handle for symmetric transfer.
151+
/** Complete immediately via dispatch.
152152
153153
Use this for immediate completion paths instead of posting to
154-
the scheduler. Sets output parameters and returns the coroutine
155-
handle to resume via symmetric transfer.
154+
the scheduler. Sets output parameters and dispatches the coroutine
155+
for resumption.
156156
*/
157-
std::coroutine_handle<> complete_immediate()
157+
void complete_immediate()
158158
{
159159
stop_cb.reset();
160160

@@ -171,7 +171,7 @@ struct overlapped_op
171171
if (bytes_out)
172172
*bytes_out = static_cast<std::size_t>(bytes_transferred);
173173

174-
return d.dispatch(h);
174+
d.dispatch(h);
175175
}
176176
};
177177

‎src/corosio/src/detail/iocp/signals.cpp‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ operator()()
157157
auto* service = svc;
158158
svc = nullptr;
159159

160-
d.dispatch(h).resume();
160+
d.dispatch(h);
161161

162162
// Balance the on_work_started() from start_wait. When svc is null
163163
// (immediate completion from queued signal), no work tracking occurred.
@@ -216,7 +216,7 @@ wait(
216216
*ec = make_error_code(capy::error::canceled);
217217
if (signal_out)
218218
*signal_out = 0;
219-
d.dispatch(h).resume();
219+
d.dispatch(h);
220220
return;
221221
}
222222

@@ -495,7 +495,7 @@ cancel_wait(win_signal_impl& impl)
495495
*op->ec_out = make_error_code(capy::error::canceled);
496496
if (op->signal_out)
497497
*op->signal_out = 0;
498-
op->d.dispatch(op->h).resume();
498+
op->d.dispatch(op->h);
499499
sched_.on_work_finished();
500500
}
501501
}

‎src/corosio/src/detail/iocp/sockets.cpp‎

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -528,16 +528,10 @@ read_some(
528528
DWORD err = ::WSAGetLastError();
529529
if (err != WSA_IO_PENDING)
530530
{
531-
// Immediate error - must use post(), not complete_immediate().
532-
// Using symmetric transfer (complete_immediate) here breaks
533-
// coroutine chains that hold async mutexes: the resumed coroutine
534-
// releases its lock and tries to wake the next waiter, but the
535-
// symmetric transfer chain doesn't return control to io_context
536-
// properly. Posting ensures the scheduler processes the completion,
537-
// calling resume_coro() which explicitly calls .resume().
531+
// Immediate error - dispatch inline
538532
svc_.work_finished();
539533
op.dwError = err;
540-
svc_.post(&op);
534+
op.complete_immediate();
541535
return;
542536
}
543537
}

‎src/corosio/src/detail/resume_coro.hpp‎

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,6 @@ namespace boost::corosio::detail {
2222
error codes, bytes transferred) written by other threads are
2323
visible to the resumed coroutine before it continues execution.
2424
25-
Uses symmetric transfer: if dispatch returns the same handle,
26-
we resume directly. If it returns noop_coroutine, the work was
27-
posted to a queue and will be resumed by the scheduler.
28-
2925
@param d The executor to dispatch through.
3026
@param h The coroutine handle to resume.
3127
*/
@@ -35,9 +31,7 @@ resume_coro(capy::executor_ref d, capy::coro h)
3531
// I/O results may have been written by another thread (OS or worker).
3632
// Acquire fence ensures those writes are visible before coroutine resumes.
3733
std::atomic_thread_fence(std::memory_order_acquire);
38-
auto resume_h = d.dispatch(h);
39-
if (resume_h.address() == h.address())
40-
resume_h.resume();
34+
d.dispatch(h);
4135
}
4236

4337
} // namespace boost::corosio::detail

‎src/corosio/src/detail/select/acceptors.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ operator()()
121121
capy::executor_ref saved_ex( std::move( ex ) );
122122
capy::coro saved_h( std::move( h ) );
123123
impl_ptr.reset();
124-
saved_ex.dispatch( saved_h ).resume();
124+
saved_ex.dispatch( saved_h );
125125
}
126126

127127
select_acceptor_impl::

‎src/corosio/src/detail/select/op.hpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ struct select_op : scheduler_op
174174
capy::executor_ref saved_ex( std::move( ex ) );
175175
capy::coro saved_h( std::move( h ) );
176176
impl_ptr.reset();
177-
saved_ex.dispatch( saved_h ).resume();
177+
saved_ex.dispatch( saved_h );
178178
}
179179

180180
virtual bool is_read_operation() const noexcept { return false; }

‎src/corosio/src/detail/select/sockets.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ operator()()
101101
capy::executor_ref saved_ex( std::move( ex ) );
102102
capy::coro saved_h( std::move( h ) );
103103
impl_ptr.reset();
104-
saved_ex.dispatch( saved_h ).resume();
104+
saved_ex.dispatch( saved_h );
105105
}
106106

107107
select_socket_impl::

0 commit comments

Comments
 (0)