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

100.0% Lines (2 / 2) -% Branches (0 / 0) 100.0% Functions (1 / 1)
win_local_stream_acceptor.hpp
f(x) Functions (1)
Line Branch TLA Hits Source Code
1 //
2 // Copyright (c) 2026 Michael Vandeberg
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/cppalliance/corosio
8 //
9
10 #ifndef BOOST_COROSIO_NATIVE_DETAIL_IOCP_WIN_LOCAL_STREAM_ACCEPTOR_HPP
11 #define BOOST_COROSIO_NATIVE_DETAIL_IOCP_WIN_LOCAL_STREAM_ACCEPTOR_HPP
12
13 #include <boost/corosio/detail/platform.hpp>
14
15 #if BOOST_COROSIO_HAS_IOCP
16
17 #include <boost/corosio/local_stream_acceptor.hpp>
18 #include <boost/corosio/wait_type.hpp>
19 #include <boost/capy/continuation.hpp>
20 #include <boost/capy/ex/executor_ref.hpp>
21 #include <boost/corosio/detail/object_ref.hpp>
22 #include <boost/corosio/detail/intrusive.hpp>
23 #include <boost/corosio/native/detail/iocp/win_overlapped_op.hpp>
24 #include <boost/corosio/native/detail/iocp/win_windows.hpp>
25 #include <boost/corosio/native/detail/endpoint_convert.hpp>
26
27 #include <coroutine>
28
29 #include <ws2tcpip.h>
30 #include <mswsock.h>
31
32 namespace boost::corosio::detail {
33
34 class win_local_stream_acceptor_service;
35 class win_local_stream_service;
36 class win_local_stream_socket;
37 class win_local_stream_acceptor;
38
39 /** Accept operation state for local stream sockets.
40
41 The addr_buf is sized for sockaddr_un (larger than sockaddr_in6).
42 */
43 struct local_stream_accept_op : overlapped_op
44 {
45 SOCKET accepted_socket = INVALID_SOCKET;
46 win_local_stream_socket* peer_wrapper = nullptr;
47 win_local_stream_acceptor& acceptor;
48 SOCKET listen_socket = INVALID_SOCKET;
49 io_object::implementation** impl_out = nullptr;
50 // 2 * (sizeof(un_sa_t) + 16) = 2 * (110 + 16) = 252
51 char addr_buf[2 * (sizeof(un_sa_t) + 16)];
52
53 static void do_complete(
54 void* owner,
55 scheduler_op* base,
56 std::uint32_t bytes,
57 std::uint32_t error);
58 static void do_cancel_impl(overlapped_op* op) noexcept;
59
60 explicit local_stream_accept_op(win_local_stream_acceptor& acceptor_) noexcept;
61 };
62
63 /** Readiness-wait operation state for a local stream acceptor. */
64 struct local_stream_acceptor_wait_op : overlapped_op
65 {
66 win_local_stream_acceptor& acceptor;
67 SOCKET listen_socket = INVALID_SOCKET;
68
69 static void do_complete(
70 void* owner,
71 scheduler_op* base,
72 std::uint32_t bytes,
73 std::uint32_t error);
74 static void do_cancel_impl(overlapped_op* op) noexcept;
75
76 explicit local_stream_acceptor_wait_op(
77 win_local_stream_acceptor& acceptor_) noexcept;
78 };
79
80 /** Acceptor implementation for IOCP local stream I/O.
81
82 Collapses the historical internal-state/wrapper split into one
83 pooled `io_object::implementation`.
84 */
85 class win_local_stream_acceptor final
86 : public local_stream_acceptor::implementation
87 , public intrusive_list<win_local_stream_acceptor>::node
88 {
89 friend class win_local_stream_service;
90 friend struct local_stream_accept_op;
91 friend struct local_stream_acceptor_wait_op;
92
93 win_local_stream_service& svc_;
94 local_stream_accept_op acc_;
95 local_stream_acceptor_wait_op wt_;
96 SOCKET socket_ = INVALID_SOCKET;
97 corosio::local_endpoint local_endpoint_;
98
99 public:
100 explicit win_local_stream_acceptor(win_local_stream_service& svc) noexcept;
101
102 /// Recycle into the owning service's pool. Defined out-of-line
103 /// after `win_local_stream_service` is complete (needs
104 /// `svc_.acceptor_pool_`).
105 void retire() noexcept override;
106
107 /** Reset recycled state for reuse.
108
109 Each op's `OVERLAPPED` fields are re-seeded by
110 `overlapped_op::reset()` at its next submit, so they are not
111 zeroed here.
112
113 @pre refs_ == 0, socket closed, no op in flight.
114 */
115 void reuse() noexcept;
116
117 win_local_stream_service& socket_service() noexcept;
118
119 std::coroutine_handle<> accept(
120 capy::continuation& cont,
121 capy::executor_ref d,
122 std::stop_token token,
123 std::error_code* ec,
124 io_object::implementation** impl_out) override;
125
126 std::coroutine_handle<> wait(
127 capy::continuation& cont,
128 capy::executor_ref d,
129 wait_type w,
130 std::stop_token token,
131 std::error_code* ec) override;
132
133 corosio::local_endpoint local_endpoint() const noexcept override;
134 bool is_open() const noexcept override;
135 void cancel() noexcept override;
136
137 native_handle_type native_handle() const noexcept override;
138
139 4x corosio::family family() const noexcept override
140 {
141 // Local sockets have no IP family; v4 is the inert value
142 4x return corosio::family::v4;
143 }
144 native_handle_type release_socket() noexcept override;
145
146 std::error_code set_option(
147 int level,
148 int optname,
149 void const* data,
150 std::size_t size) noexcept override;
151 std::error_code
152 get_option(int level, int optname, void* data, std::size_t* size)
153 const noexcept override;
154
155 void set_local_endpoint(corosio::local_endpoint ep) noexcept;
156 void close_socket() noexcept;
157 };
158
159 } // namespace boost::corosio::detail
160
161 #endif // BOOST_COROSIO_HAS_IOCP
162
163 #endif // BOOST_COROSIO_NATIVE_DETAIL_IOCP_WIN_LOCAL_STREAM_ACCEPTOR_HPP
164