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

100.0% Lines (2/2) 100.0% List of functions (1/1) -% Branches (0/0)
win_local_stream_acceptor.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_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/ex/executor_ref.hpp>
20 #include <boost/corosio/detail/intrusive.hpp>
21 #include <boost/corosio/native/detail/iocp/win_overlapped_op.hpp>
22 #include <boost/corosio/native/detail/iocp/win_windows.hpp>
23 #include <boost/corosio/native/detail/endpoint_convert.hpp>
24
25 #include <coroutine>
26 #include <memory>
27
28 #include <ws2tcpip.h>
29 #include <mswsock.h>
30
31 namespace boost::corosio::detail {
32
33 class win_local_stream_acceptor_service;
34 class win_local_stream_service;
35 class win_local_stream_socket;
36 class win_local_stream_acceptor_internal;
37
38 /** Accept operation state for local stream sockets.
39
40 The addr_buf is sized for sockaddr_un (larger than sockaddr_in6).
41 */
42 struct local_stream_accept_op : overlapped_op
43 {
44 SOCKET accepted_socket = INVALID_SOCKET;
45 win_local_stream_socket* peer_wrapper = nullptr;
46 std::shared_ptr<win_local_stream_acceptor_internal> acceptor_ptr;
47 SOCKET listen_socket = INVALID_SOCKET;
48 io_object::implementation** impl_out = nullptr;
49 // 2 * (sizeof(un_sa_t) + 16) = 2 * (110 + 16) = 252
50 char addr_buf[2 * (sizeof(un_sa_t) + 16)];
51
52 static void do_complete(
53 void* owner,
54 scheduler_op* base,
55 std::uint32_t bytes,
56 std::uint32_t error);
57 static void do_cancel_impl(overlapped_op* op) noexcept;
58
59 local_stream_accept_op() noexcept;
60 };
61
62 /** Readiness-wait operation state for a local stream acceptor. */
63 struct local_stream_acceptor_wait_op : overlapped_op
64 {
65 std::shared_ptr<win_local_stream_acceptor_internal> acceptor_ptr;
66 SOCKET listen_socket = INVALID_SOCKET;
67
68 static void do_complete(
69 void* owner,
70 scheduler_op* base,
71 std::uint32_t bytes,
72 std::uint32_t error);
73 static void do_cancel_impl(overlapped_op* op) noexcept;
74
75 local_stream_acceptor_wait_op() noexcept;
76 };
77
78 /* Internal acceptor state for IOCP local stream I/O. */
79 class win_local_stream_acceptor_internal
80 : public intrusive_list<win_local_stream_acceptor_internal>::node
81 , public std::enable_shared_from_this<win_local_stream_acceptor_internal>
82 {
83 friend class win_local_stream_service;
84 friend class win_local_stream_acceptor;
85
86 public:
87 explicit win_local_stream_acceptor_internal(
88 win_local_stream_service& svc) noexcept;
89 ~win_local_stream_acceptor_internal();
90
91 win_local_stream_service& socket_service() noexcept;
92
93 std::coroutine_handle<> accept(
94 std::coroutine_handle<>,
95 capy::executor_ref,
96 std::stop_token,
97 std::error_code*,
98 io_object::implementation**);
99
100 std::coroutine_handle<> wait(
101 std::coroutine_handle<>,
102 capy::executor_ref,
103 wait_type,
104 std::stop_token,
105 std::error_code*);
106
107 SOCKET native_handle() const noexcept;
108 corosio::local_endpoint local_endpoint() const noexcept;
109 bool is_open() const noexcept;
110 void cancel() noexcept;
111 void close_socket() noexcept;
112 void set_local_endpoint(corosio::local_endpoint ep) noexcept;
113
114 local_stream_accept_op acc_;
115 local_stream_acceptor_wait_op wt_;
116
117 private:
118 win_local_stream_service& svc_;
119 SOCKET socket_ = INVALID_SOCKET;
120 corosio::local_endpoint local_endpoint_;
121 };
122
123 /* Acceptor implementation wrapper for IOCP local stream I/O. */
124 class win_local_stream_acceptor final
125 : public local_stream_acceptor::implementation
126 , public intrusive_list<win_local_stream_acceptor>::node
127 {
128 std::shared_ptr<win_local_stream_acceptor_internal> internal_;
129
130 public:
131 explicit win_local_stream_acceptor(
132 std::shared_ptr<win_local_stream_acceptor_internal> internal) noexcept;
133
134 void close_internal() noexcept;
135
136 std::coroutine_handle<> accept(
137 std::coroutine_handle<> h,
138 capy::executor_ref d,
139 std::stop_token token,
140 std::error_code* ec,
141 io_object::implementation** impl_out) override;
142
143 std::coroutine_handle<> wait(
144 std::coroutine_handle<> h,
145 capy::executor_ref d,
146 wait_type w,
147 std::stop_token token,
148 std::error_code* ec) override;
149
150 corosio::local_endpoint local_endpoint() const noexcept override;
151 bool is_open() const noexcept override;
152 void cancel() noexcept override;
153
154 native_handle_type native_handle() const noexcept override;
155
156 4x corosio::family family() const noexcept override
157 {
158 // Local sockets have no IP family; v4 is the inert value
159 4x return corosio::family::v4;
160 }
161 native_handle_type release_socket() noexcept override;
162
163 std::error_code set_option(
164 int level,
165 int optname,
166 void const* data,
167 std::size_t size) noexcept override;
168 std::error_code
169 get_option(int level, int optname, void* data, std::size_t* size)
170 const noexcept override;
171
172 win_local_stream_acceptor_internal* get_internal() const noexcept;
173 };
174
175 } // namespace boost::corosio::detail
176
177 #endif // BOOST_COROSIO_HAS_IOCP
178
179 #endif // BOOST_COROSIO_NATIVE_DETAIL_IOCP_WIN_LOCAL_STREAM_ACCEPTOR_HPP
180