Skip to content

Commit b6bdaec

Browse files
committed
Remove cached_initiator: inline WSARecv/WSASend into IOCP read_some/write_some
The cached_initiator trampoline coroutine deferred WSARecv/WSASend until after the caller suspended, but await_suspend already guarantees the caller's frame is saved. Inline the I/O calls directly and return std::noop_coroutine(), matching the pattern connect() already uses.
1 parent a2a3c43 commit b6bdaec

3 files changed

Lines changed: 49 additions & 186 deletions

File tree

include/boost/corosio/detail/cached_initiator.hpp

Lines changed: 0 additions & 114 deletions
This file was deleted.

include/boost/corosio/native/detail/iocp/win_acceptor_service.hpp

Lines changed: 49 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -449,64 +449,6 @@ win_socket_internal::connect(
449449
return std::noop_coroutine();
450450
}
451451

452-
inline void
453-
win_socket_internal::do_read_io()
454-
{
455-
auto& op = rd_;
456-
457-
op.flags = 0;
458-
459-
svc_.work_started();
460-
461-
int result = ::WSARecv(
462-
socket_, op.wsabufs, op.wsabuf_count, nullptr, &op.flags, &op, nullptr);
463-
464-
if (result == SOCKET_ERROR)
465-
{
466-
DWORD err = ::WSAGetLastError();
467-
if (err != WSA_IO_PENDING)
468-
{
469-
// Defer to avoid resuming on the initiator's stack.
470-
svc_.work_finished();
471-
op.dwError = err;
472-
svc_.post(&op);
473-
return;
474-
}
475-
}
476-
// I/O is now pending. If stop was requested before WSARecv
477-
// started, the CancelIoEx in the stop callback had nothing
478-
// to cancel. Re-check and cancel the now-pending operation.
479-
if (op.cancelled.load(std::memory_order_acquire))
480-
::CancelIoEx(reinterpret_cast<HANDLE>(socket_), &op);
481-
}
482-
483-
inline void
484-
win_socket_internal::do_write_io()
485-
{
486-
auto& op = wr_;
487-
488-
svc_.work_started();
489-
490-
int result = ::WSASend(
491-
socket_, op.wsabufs, op.wsabuf_count, nullptr, 0, &op, nullptr);
492-
493-
if (result == SOCKET_ERROR)
494-
{
495-
DWORD err = ::WSAGetLastError();
496-
if (err != WSA_IO_PENDING)
497-
{
498-
// Immediate error - must use post().
499-
svc_.work_finished();
500-
op.dwError = err;
501-
svc_.post(&op);
502-
return;
503-
}
504-
}
505-
// Re-check cancellation after I/O is pending
506-
if (op.cancelled.load(std::memory_order_acquire))
507-
::CancelIoEx(reinterpret_cast<HANDLE>(socket_), &op);
508-
}
509-
510452
inline std::coroutine_handle<>
511453
win_socket_internal::read_some(
512454
std::coroutine_handle<> h,
@@ -549,8 +491,33 @@ win_socket_internal::read_some(
549491
op.wsabufs[i].len = static_cast<ULONG>(bufs[i].size());
550492
}
551493

552-
// Symmetric transfer to initiator - I/O starts after caller is suspended
553-
return read_initiator_.start<&win_socket_internal::do_read_io>(this);
494+
// Issue WSARecv directly — caller is already suspended
495+
op.flags = 0;
496+
497+
svc_.work_started();
498+
499+
int result = ::WSARecv(
500+
socket_, op.wsabufs, op.wsabuf_count, nullptr, &op.flags, &op,
501+
nullptr);
502+
503+
if (result == SOCKET_ERROR)
504+
{
505+
DWORD err = ::WSAGetLastError();
506+
if (err != WSA_IO_PENDING)
507+
{
508+
svc_.work_finished();
509+
op.dwError = err;
510+
svc_.post(&op);
511+
return std::noop_coroutine();
512+
}
513+
}
514+
// I/O is now pending. If stop was requested before WSARecv
515+
// started, the CancelIoEx in the stop callback had nothing
516+
// to cancel. Re-check and cancel the now-pending operation.
517+
if (op.cancelled.load(std::memory_order_acquire))
518+
::CancelIoEx(reinterpret_cast<HANDLE>(socket_), &op);
519+
520+
return std::noop_coroutine();
554521
}
555522

556523
inline std::coroutine_handle<>
@@ -593,8 +560,28 @@ win_socket_internal::write_some(
593560
op.wsabufs[i].len = static_cast<ULONG>(bufs[i].size());
594561
}
595562

596-
// Symmetric transfer to initiator - I/O starts after caller is suspended
597-
return write_initiator_.start<&win_socket_internal::do_write_io>(this);
563+
// Issue WSASend directly — caller is already suspended
564+
svc_.work_started();
565+
566+
int result = ::WSASend(
567+
socket_, op.wsabufs, op.wsabuf_count, nullptr, 0, &op, nullptr);
568+
569+
if (result == SOCKET_ERROR)
570+
{
571+
DWORD err = ::WSAGetLastError();
572+
if (err != WSA_IO_PENDING)
573+
{
574+
svc_.work_finished();
575+
op.dwError = err;
576+
svc_.post(&op);
577+
return std::noop_coroutine();
578+
}
579+
}
580+
// Re-check cancellation after I/O is pending
581+
if (op.cancelled.load(std::memory_order_acquire))
582+
::CancelIoEx(reinterpret_cast<HANDLE>(socket_), &op);
583+
584+
return std::noop_coroutine();
598585
}
599586

600587
inline void

include/boost/corosio/native/detail/iocp/win_socket.hpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
#include <boost/corosio/tcp_socket.hpp>
2020
#include <boost/capy/ex/executor_ref.hpp>
2121
#include <boost/corosio/detail/intrusive.hpp>
22-
#include <boost/corosio/detail/cached_initiator.hpp>
2322
#include <boost/corosio/native/detail/iocp/win_overlapped_op.hpp>
2423
#include <boost/corosio/native/detail/iocp/win_windows.hpp>
2524

@@ -113,9 +112,6 @@ class win_socket_internal
113112
write_op wr_;
114113
SOCKET socket_ = INVALID_SOCKET;
115114

116-
cached_initiator read_initiator_;
117-
cached_initiator write_initiator_;
118-
119115
public:
120116
explicit win_socket_internal(win_sockets& svc) noexcept;
121117
~win_socket_internal();
@@ -152,12 +148,6 @@ class win_socket_internal
152148
void set_socket(SOCKET s) noexcept;
153149
void set_endpoints(endpoint local, endpoint remote) noexcept;
154150

155-
/** Execute the read I/O operation (called by initiator coroutine). */
156-
void do_read_io();
157-
158-
/** Execute the write I/O operation (called by initiator coroutine). */
159-
void do_write_io();
160-
161151
private:
162152
endpoint local_endpoint_;
163153
endpoint remote_endpoint_;

0 commit comments

Comments
 (0)