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

100.0% Lines (6/6) 100.0% List of functions (3/3) -% Branches (0/0)
win_tcp_service.hpp
f(x) Functions (3)
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2025 Vinnie Falco ([email protected])
3 // Copyright (c) 2026 Steve Gerbino
4 //
5 // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // Official repository: https://github.com/cppalliance/corosio
9 //
10
11 #ifndef BOOST_COROSIO_NATIVE_DETAIL_IOCP_WIN_TCP_SERVICE_HPP
12 #define BOOST_COROSIO_NATIVE_DETAIL_IOCP_WIN_TCP_SERVICE_HPP
13
14 #include <boost/corosio/detail/platform.hpp>
15
16 #if BOOST_COROSIO_HAS_IOCP
17
18 #include <boost/corosio/detail/config.hpp>
19 #include <boost/capy/ex/execution_context.hpp>
20 #include <boost/corosio/detail/intrusive.hpp>
21 #include <boost/corosio/native/detail/iocp/win_mutex.hpp>
22 #include <boost/corosio/native/detail/iocp/win_wsa_init.hpp>
23 #include <boost/corosio/native/detail/iocp/win_windows.hpp>
24
25 #include <boost/corosio/native/detail/iocp/win_tcp_socket.hpp>
26
27 #include <MSWSock.h>
28
29 namespace boost::corosio::detail {
30
31 class win_scheduler;
32 class win_tcp_acceptor;
33 class win_tcp_acceptor_internal;
34 class win_tcp_acceptor_service;
35
36 /** Windows IOCP socket management service.
37
38 This service owns all socket implementations and coordinates their
39 lifecycle with the IOCP. It provides:
40
41 - Socket implementation allocation and deallocation
42 - IOCP handle association for sockets
43 - Function pointer loading for ConnectEx/AcceptEx
44 - Graceful shutdown - destroys all implementations when io_context stops
45
46 @par Thread Safety
47 All public member functions are thread-safe.
48
49 @note Only available on Windows platforms.
50 */
51 class BOOST_COROSIO_DECL win_tcp_service final
52 : private win_wsa_init
53 , public capy::execution_context::service
54 , public io_object::io_service
55 {
56 public:
57 using key_type = win_tcp_service;
58
59 io_object::implementation* construct() override;
60
61 void destroy(io_object::implementation* p) override;
62
63 void close(io_object::handle& h) override;
64
65 /** Construct the socket service.
66
67 Obtains the IOCP handle from the scheduler service and
68 loads extension function pointers.
69
70 @param ctx Reference to the owning execution_context.
71 */
72 explicit win_tcp_service(capy::execution_context& ctx);
73
74 /** Destroy the socket service. */
75 ~win_tcp_service();
76
77 win_tcp_service(win_tcp_service const&) = delete;
78 win_tcp_service& operator=(win_tcp_service const&) = delete;
79
80 /** Shut down the service. */
81 void shutdown() override;
82
83 /** Destroy a socket implementation wrapper.
84 Removes from tracking list and deletes.
85 */
86 void destroy_impl(win_tcp_socket& impl);
87
88 /** Unregister a socket implementation from the service list.
89 Called by the internal impl destructor.
90 */
91 void unregister_impl(win_tcp_socket_internal& impl);
92
93 /** Create and register a socket with the IOCP.
94
95 @param impl The socket implementation internal to initialize.
96 @return Error code, or success.
97 */
98 std::error_code
99 open_socket(win_tcp_socket_internal& impl, int family, int type, int protocol);
100
101 /** Bind a stream socket to a local endpoint.
102
103 @param impl The socket implementation internal to bind.
104 @param ep The local endpoint to bind to.
105 @return Error code, or success.
106 */
107 std::error_code
108 bind_socket(win_tcp_socket_internal& impl, endpoint ep);
109
110 /** Destroy an acceptor implementation wrapper.
111 Removes from tracking list and deletes.
112 */
113 void destroy_acceptor_impl(win_tcp_acceptor& impl);
114
115 /** Unregister an acceptor implementation from the service list.
116 Called by the internal impl destructor.
117 */
118 void unregister_acceptor_impl(win_tcp_acceptor_internal& impl);
119
120 /** Create an acceptor socket without binding or listening.
121
122 Creates a socket and associates it with the IOCP.
123 For IPv6, dual-stack is enabled by default.
124 Does not set SO_REUSEADDR.
125
126 @param impl The acceptor implementation internal to initialize.
127 @param family Address family (e.g. `AF_INET`, `AF_INET6`).
128 @param type Socket type (e.g. `SOCK_STREAM`).
129 @param protocol Protocol number (e.g. `IPPROTO_TCP`).
130 @return Error code, or success.
131 */
132 std::error_code open_acceptor_socket(
133 win_tcp_acceptor_internal& impl, int family, int type, int protocol);
134
135 /** Bind an open acceptor to a local endpoint.
136
137 @param impl The acceptor implementation internal.
138 @param ep The local endpoint to bind to.
139 @return Error code, or success.
140 */
141 std::error_code bind_acceptor(win_tcp_acceptor_internal& impl, endpoint ep);
142
143 /** Start listening for incoming connections.
144
145 @param impl The acceptor implementation internal.
146 @param backlog The listen backlog.
147 @return Error code, or success.
148 */
149 std::error_code listen_acceptor(win_tcp_acceptor_internal& impl, int backlog);
150
151 /** Return the IOCP handle. */
152 void* native_handle() const noexcept;
153
154 /** Return the ConnectEx function pointer. */
155 1385x LPFN_CONNECTEX connect_ex() const noexcept
156 {
157 1385x return connect_ex_;
158 }
159
160 /** Return the AcceptEx function pointer. */
161 1386x LPFN_ACCEPTEX accept_ex() const noexcept
162 {
163 1386x return accept_ex_;
164 }
165
166 /** Post an overlapped operation for completion. */
167 void post(overlapped_op* op);
168
169 /** Signal that an overlapped I/O is now pending (CAS protocol). */
170 void on_pending(overlapped_op* op) noexcept;
171
172 /** Post an immediate completion with pre-stored results. */
173 void on_completion(overlapped_op* op, DWORD error, DWORD bytes) noexcept;
174
175 /** Notify scheduler of pending I/O work. */
176 void work_started() noexcept;
177
178 /** Notify scheduler that I/O work completed. */
179 void work_finished() noexcept;
180
181 /** Return the owning IOCP scheduler. */
182 20162x win_scheduler& scheduler() noexcept
183 {
184 20162x return sched_;
185 }
186
187 private:
188 friend class win_tcp_acceptor_service;
189
190 void load_extension_functions();
191
192 win_scheduler& sched_;
193 win_mutex mutex_;
194 intrusive_list<win_tcp_socket_internal> socket_list_;
195 intrusive_list<win_tcp_acceptor_internal> acceptor_list_;
196 intrusive_list<win_tcp_socket> socket_wrapper_list_;
197 intrusive_list<win_tcp_acceptor> acceptor_wrapper_list_;
198 void* iocp_;
199 LPFN_CONNECTEX connect_ex_ = nullptr;
200 LPFN_ACCEPTEX accept_ex_ = nullptr;
201 };
202
203 } // namespace boost::corosio::detail
204
205 #endif // BOOST_COROSIO_HAS_IOCP
206
207 #endif // BOOST_COROSIO_NATIVE_DETAIL_IOCP_WIN_TCP_SERVICE_HPP
208