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

100.0% Lines (2/2) 100.0% List of functions (1/1) -% Branches (0/0)
win_local_stream_socket.hpp
f(x) Functions (1)
Line 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_SOCKET_HPP
11 #define BOOST_COROSIO_NATIVE_DETAIL_IOCP_WIN_LOCAL_STREAM_SOCKET_HPP
12
13 #include <boost/corosio/detail/platform.hpp>
14
15 #if BOOST_COROSIO_HAS_IOCP
16
17 #include <boost/corosio/detail/config.hpp>
18 #include <boost/corosio/local_stream_socket.hpp>
19 #include <boost/corosio/wait_type.hpp>
20 #include <boost/capy/ex/executor_ref.hpp>
21 #include <boost/corosio/detail/intrusive.hpp>
22 #include <boost/corosio/native/detail/iocp/win_overlapped_op.hpp>
23 #include <boost/corosio/native/detail/iocp/win_windows.hpp>
24
25 #include <coroutine>
26 #include <memory>
27
28 #include <mswsock.h>
29
30 namespace boost::corosio::detail {
31
32 class win_local_stream_service;
33 class win_local_stream_socket_internal;
34
35 /** Connect operation state for local stream sockets. */
36 struct local_stream_connect_op : overlapped_op
37 {
38 win_local_stream_socket_internal& internal;
39 std::shared_ptr<win_local_stream_socket_internal> internal_ptr;
40 corosio::local_endpoint target_endpoint;
41
42 static void do_complete(
43 void* owner,
44 scheduler_op* base,
45 std::uint32_t bytes,
46 std::uint32_t error);
47 static void do_cancel_impl(overlapped_op* op) noexcept;
48
49 explicit local_stream_connect_op(
50 win_local_stream_socket_internal& internal_) noexcept;
51 };
52
53 /** Read operation state for local stream sockets. */
54 struct local_stream_read_op : overlapped_op
55 {
56 static constexpr std::size_t max_buffers = 16;
57 WSABUF wsabufs[max_buffers];
58 DWORD wsabuf_count = 0;
59 DWORD flags = 0;
60 win_local_stream_socket_internal& internal;
61 std::shared_ptr<win_local_stream_socket_internal> internal_ptr;
62
63 static void do_complete(
64 void* owner,
65 scheduler_op* base,
66 std::uint32_t bytes,
67 std::uint32_t error);
68 static void do_cancel_impl(overlapped_op* op) noexcept;
69
70 explicit local_stream_read_op(
71 win_local_stream_socket_internal& internal_) noexcept;
72 };
73
74 /** Write operation state for local stream sockets. */
75 struct local_stream_write_op : overlapped_op
76 {
77 static constexpr std::size_t max_buffers = 16;
78 WSABUF wsabufs[max_buffers];
79 DWORD wsabuf_count = 0;
80 win_local_stream_socket_internal& internal;
81 std::shared_ptr<win_local_stream_socket_internal> internal_ptr;
82
83 static void do_complete(
84 void* owner,
85 scheduler_op* base,
86 std::uint32_t bytes,
87 std::uint32_t error);
88 static void do_cancel_impl(overlapped_op* op) noexcept;
89
90 explicit local_stream_write_op(
91 win_local_stream_socket_internal& internal_) noexcept;
92 };
93
94 /** Readiness-wait operation state for local stream sockets. */
95 struct local_stream_wait_op : overlapped_op
96 {
97 WSABUF wsabuf{};
98 DWORD flags = 0;
99 wait_type w = wait_type::read;
100 win_local_stream_socket_internal& internal;
101 std::shared_ptr<win_local_stream_socket_internal> internal_ptr;
102
103 static void do_complete(
104 void* owner,
105 scheduler_op* base,
106 std::uint32_t bytes,
107 std::uint32_t error);
108 static void do_cancel_impl(overlapped_op* op) noexcept;
109
110 explicit local_stream_wait_op(
111 win_local_stream_socket_internal& internal_) noexcept;
112 };
113
114 /* Internal socket state for IOCP local stream I/O.
115
116 Holds the native SOCKET handle, cached endpoints, and
117 pending operation slots. Derives from enable_shared_from_this
118 so in-flight operations can extend its lifetime past the
119 wrapper's destruction.
120 */
121 class win_local_stream_socket_internal
122 : public intrusive_list<win_local_stream_socket_internal>::node
123 , public std::enable_shared_from_this<win_local_stream_socket_internal>
124 {
125 friend class win_local_stream_service;
126 friend class win_local_stream_socket;
127 friend struct local_stream_read_op;
128 friend struct local_stream_write_op;
129 friend struct local_stream_connect_op;
130 friend struct local_stream_wait_op;
131
132 win_local_stream_service& svc_;
133 local_stream_connect_op conn_;
134 local_stream_read_op rd_;
135 local_stream_write_op wr_;
136 local_stream_wait_op wt_;
137 SOCKET socket_ = INVALID_SOCKET;
138
139 public:
140 explicit win_local_stream_socket_internal(
141 win_local_stream_service& svc) noexcept;
142 ~win_local_stream_socket_internal();
143
144 std::coroutine_handle<> connect(
145 std::coroutine_handle<>,
146 capy::executor_ref,
147 corosio::local_endpoint,
148 std::stop_token,
149 std::error_code*);
150
151 std::coroutine_handle<> read_some(
152 std::coroutine_handle<>,
153 capy::executor_ref,
154 buffer_param,
155 std::stop_token,
156 std::error_code*,
157 std::size_t*);
158
159 std::coroutine_handle<> write_some(
160 std::coroutine_handle<>,
161 capy::executor_ref,
162 buffer_param,
163 std::stop_token,
164 std::error_code*,
165 std::size_t*);
166
167 std::coroutine_handle<> wait(
168 std::coroutine_handle<>,
169 capy::executor_ref,
170 wait_type,
171 std::stop_token,
172 std::error_code*);
173
174 SOCKET native_handle() const noexcept;
175 corosio::local_endpoint local_endpoint() const noexcept;
176 corosio::local_endpoint remote_endpoint() const noexcept;
177 bool is_open() const noexcept;
178 void cancel() noexcept;
179 void close_socket() noexcept;
180 void set_socket(SOCKET s) noexcept;
181 void set_endpoints(
182 corosio::local_endpoint local, corosio::local_endpoint remote) noexcept;
183
184 private:
185 corosio::local_endpoint local_endpoint_;
186 corosio::local_endpoint remote_endpoint_;
187 };
188
189 /* Socket implementation wrapper for IOCP local stream I/O.
190
191 Public-facing implementation holding a shared_ptr to the
192 internal state. Inherits from local_stream_socket::implementation
193 to satisfy the virtual interface.
194 */
195 class win_local_stream_socket final
196 : public local_stream_socket::implementation
197 , public intrusive_list<win_local_stream_socket>::node
198 {
199 std::shared_ptr<win_local_stream_socket_internal> internal_;
200
201 public:
202 explicit win_local_stream_socket(
203 std::shared_ptr<win_local_stream_socket_internal> internal) noexcept;
204
205 void close_internal() noexcept;
206
207 std::coroutine_handle<> connect(
208 std::coroutine_handle<> h,
209 capy::executor_ref d,
210 corosio::local_endpoint ep,
211 std::stop_token token,
212 std::error_code* ec) override;
213
214 std::coroutine_handle<> read_some(
215 std::coroutine_handle<> h,
216 capy::executor_ref d,
217 buffer_param buf,
218 std::stop_token token,
219 std::error_code* ec,
220 std::size_t* bytes) override;
221
222 std::coroutine_handle<> write_some(
223 std::coroutine_handle<> h,
224 capy::executor_ref d,
225 buffer_param buf,
226 std::stop_token token,
227 std::error_code* ec,
228 std::size_t* bytes) override;
229
230 std::coroutine_handle<> wait(
231 std::coroutine_handle<> h,
232 capy::executor_ref d,
233 wait_type w,
234 std::stop_token token,
235 std::error_code* ec) override;
236
237 std::error_code
238 shutdown(local_stream_socket::shutdown_type what) noexcept override;
239
240 native_handle_type native_handle() const noexcept override;
241
242 5x corosio::family family() const noexcept override
243 {
244 // Local sockets have no IP family; v4 is the inert value
245 5x return corosio::family::v4;
246 }
247
248 native_handle_type release_socket() noexcept override;
249
250 std::error_code set_option(
251 int level,
252 int optname,
253 void const* data,
254 std::size_t size) noexcept override;
255 std::error_code
256 get_option(int level, int optname, void* data, std::size_t* size)
257 const noexcept override;
258
259 corosio::local_endpoint local_endpoint() const noexcept override;
260 corosio::local_endpoint remote_endpoint() const noexcept override;
261 void cancel() noexcept override;
262
263 win_local_stream_socket_internal* get_internal() const noexcept;
264 };
265
266 } // namespace boost::corosio::detail
267
268 #endif // BOOST_COROSIO_HAS_IOCP
269
270 #endif // BOOST_COROSIO_NATIVE_DETAIL_IOCP_WIN_LOCAL_STREAM_SOCKET_HPP
271