]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // |
2 | // socket_acceptor_service.hpp | |
3 | // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
4 | // | |
b32b8144 | 5 | // Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) |
7c673cae FG |
6 | // |
7 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |
8 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
9 | // | |
10 | ||
11 | #ifndef BOOST_ASIO_SOCKET_ACCEPTOR_SERVICE_HPP | |
12 | #define BOOST_ASIO_SOCKET_ACCEPTOR_SERVICE_HPP | |
13 | ||
14 | #if defined(_MSC_VER) && (_MSC_VER >= 1200) | |
15 | # pragma once | |
16 | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) | |
17 | ||
18 | #include <boost/asio/detail/config.hpp> | |
b32b8144 FG |
19 | |
20 | #if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) | |
21 | ||
7c673cae FG |
22 | #include <boost/asio/basic_socket.hpp> |
23 | #include <boost/asio/detail/type_traits.hpp> | |
24 | #include <boost/asio/error.hpp> | |
b32b8144 | 25 | #include <boost/asio/io_context.hpp> |
7c673cae FG |
26 | |
27 | #if defined(BOOST_ASIO_WINDOWS_RUNTIME) | |
28 | # include <boost/asio/detail/null_socket_service.hpp> | |
29 | #elif defined(BOOST_ASIO_HAS_IOCP) | |
30 | # include <boost/asio/detail/win_iocp_socket_service.hpp> | |
31 | #else | |
32 | # include <boost/asio/detail/reactive_socket_service.hpp> | |
33 | #endif | |
34 | ||
35 | #include <boost/asio/detail/push_options.hpp> | |
36 | ||
37 | namespace boost { | |
38 | namespace asio { | |
39 | ||
40 | /// Default service implementation for a socket acceptor. | |
41 | template <typename Protocol> | |
42 | class socket_acceptor_service | |
43 | #if defined(GENERATING_DOCUMENTATION) | |
b32b8144 | 44 | : public boost::asio::io_context::service |
7c673cae FG |
45 | #else |
46 | : public boost::asio::detail::service_base<socket_acceptor_service<Protocol> > | |
47 | #endif | |
48 | { | |
49 | public: | |
50 | #if defined(GENERATING_DOCUMENTATION) | |
51 | /// The unique service identifier. | |
b32b8144 | 52 | static boost::asio::io_context::id id; |
7c673cae FG |
53 | #endif |
54 | ||
55 | /// The protocol type. | |
56 | typedef Protocol protocol_type; | |
57 | ||
58 | /// The endpoint type. | |
59 | typedef typename protocol_type::endpoint endpoint_type; | |
60 | ||
61 | private: | |
62 | // The type of the platform-specific implementation. | |
63 | #if defined(BOOST_ASIO_WINDOWS_RUNTIME) | |
64 | typedef detail::null_socket_service<Protocol> service_impl_type; | |
65 | #elif defined(BOOST_ASIO_HAS_IOCP) | |
66 | typedef detail::win_iocp_socket_service<Protocol> service_impl_type; | |
67 | #else | |
68 | typedef detail::reactive_socket_service<Protocol> service_impl_type; | |
69 | #endif | |
70 | ||
71 | public: | |
72 | /// The native type of the socket acceptor. | |
73 | #if defined(GENERATING_DOCUMENTATION) | |
74 | typedef implementation_defined implementation_type; | |
75 | #else | |
76 | typedef typename service_impl_type::implementation_type implementation_type; | |
77 | #endif | |
78 | ||
7c673cae FG |
79 | /// The native acceptor type. |
80 | #if defined(GENERATING_DOCUMENTATION) | |
81 | typedef implementation_defined native_handle_type; | |
82 | #else | |
83 | typedef typename service_impl_type::native_handle_type native_handle_type; | |
84 | #endif | |
85 | ||
b32b8144 FG |
86 | /// Construct a new socket acceptor service for the specified io_context. |
87 | explicit socket_acceptor_service(boost::asio::io_context& io_context) | |
7c673cae | 88 | : boost::asio::detail::service_base< |
b32b8144 FG |
89 | socket_acceptor_service<Protocol> >(io_context), |
90 | service_impl_(io_context) | |
7c673cae FG |
91 | { |
92 | } | |
93 | ||
94 | /// Construct a new socket acceptor implementation. | |
95 | void construct(implementation_type& impl) | |
96 | { | |
97 | service_impl_.construct(impl); | |
98 | } | |
99 | ||
100 | #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) | |
101 | /// Move-construct a new socket acceptor implementation. | |
102 | void move_construct(implementation_type& impl, | |
103 | implementation_type& other_impl) | |
104 | { | |
105 | service_impl_.move_construct(impl, other_impl); | |
106 | } | |
107 | ||
108 | /// Move-assign from another socket acceptor implementation. | |
109 | void move_assign(implementation_type& impl, | |
110 | socket_acceptor_service& other_service, | |
111 | implementation_type& other_impl) | |
112 | { | |
113 | service_impl_.move_assign(impl, other_service.service_impl_, other_impl); | |
114 | } | |
115 | ||
b32b8144 FG |
116 | // All acceptor services have access to each other's implementations. |
117 | template <typename Protocol1> friend class socket_acceptor_service; | |
118 | ||
7c673cae FG |
119 | /// Move-construct a new socket acceptor implementation from another protocol |
120 | /// type. | |
121 | template <typename Protocol1> | |
122 | void converting_move_construct(implementation_type& impl, | |
b32b8144 | 123 | socket_acceptor_service<Protocol1>& other_service, |
7c673cae FG |
124 | typename socket_acceptor_service< |
125 | Protocol1>::implementation_type& other_impl, | |
126 | typename enable_if<is_convertible< | |
127 | Protocol1, Protocol>::value>::type* = 0) | |
128 | { | |
129 | service_impl_.template converting_move_construct<Protocol1>( | |
b32b8144 | 130 | impl, other_service.service_impl_, other_impl); |
7c673cae FG |
131 | } |
132 | #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) | |
133 | ||
134 | /// Destroy a socket acceptor implementation. | |
135 | void destroy(implementation_type& impl) | |
136 | { | |
137 | service_impl_.destroy(impl); | |
138 | } | |
139 | ||
140 | /// Open a new socket acceptor implementation. | |
b32b8144 | 141 | BOOST_ASIO_SYNC_OP_VOID open(implementation_type& impl, |
7c673cae FG |
142 | const protocol_type& protocol, boost::system::error_code& ec) |
143 | { | |
b32b8144 FG |
144 | service_impl_.open(impl, protocol, ec); |
145 | BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); | |
7c673cae FG |
146 | } |
147 | ||
148 | /// Assign an existing native acceptor to a socket acceptor. | |
b32b8144 | 149 | BOOST_ASIO_SYNC_OP_VOID assign(implementation_type& impl, |
7c673cae FG |
150 | const protocol_type& protocol, const native_handle_type& native_acceptor, |
151 | boost::system::error_code& ec) | |
152 | { | |
b32b8144 FG |
153 | service_impl_.assign(impl, protocol, native_acceptor, ec); |
154 | BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); | |
7c673cae FG |
155 | } |
156 | ||
157 | /// Determine whether the acceptor is open. | |
158 | bool is_open(const implementation_type& impl) const | |
159 | { | |
160 | return service_impl_.is_open(impl); | |
161 | } | |
162 | ||
163 | /// Cancel all asynchronous operations associated with the acceptor. | |
b32b8144 | 164 | BOOST_ASIO_SYNC_OP_VOID cancel(implementation_type& impl, |
7c673cae FG |
165 | boost::system::error_code& ec) |
166 | { | |
b32b8144 FG |
167 | service_impl_.cancel(impl, ec); |
168 | BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); | |
7c673cae FG |
169 | } |
170 | ||
171 | /// Bind the socket acceptor to the specified local endpoint. | |
b32b8144 | 172 | BOOST_ASIO_SYNC_OP_VOID bind(implementation_type& impl, |
7c673cae FG |
173 | const endpoint_type& endpoint, boost::system::error_code& ec) |
174 | { | |
b32b8144 FG |
175 | service_impl_.bind(impl, endpoint, ec); |
176 | BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); | |
7c673cae FG |
177 | } |
178 | ||
179 | /// Place the socket acceptor into the state where it will listen for new | |
180 | /// connections. | |
b32b8144 | 181 | BOOST_ASIO_SYNC_OP_VOID listen(implementation_type& impl, int backlog, |
7c673cae FG |
182 | boost::system::error_code& ec) |
183 | { | |
b32b8144 FG |
184 | service_impl_.listen(impl, backlog, ec); |
185 | BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); | |
7c673cae FG |
186 | } |
187 | ||
188 | /// Close a socket acceptor implementation. | |
b32b8144 | 189 | BOOST_ASIO_SYNC_OP_VOID close(implementation_type& impl, |
7c673cae FG |
190 | boost::system::error_code& ec) |
191 | { | |
b32b8144 FG |
192 | service_impl_.close(impl, ec); |
193 | BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); | |
7c673cae FG |
194 | } |
195 | ||
b32b8144 FG |
196 | /// Release ownership of the underlying acceptor. |
197 | native_handle_type release(implementation_type& impl, | |
198 | boost::system::error_code& ec) | |
7c673cae | 199 | { |
b32b8144 | 200 | return service_impl_.release(impl, ec); |
7c673cae FG |
201 | } |
202 | ||
203 | /// Get the native acceptor implementation. | |
204 | native_handle_type native_handle(implementation_type& impl) | |
205 | { | |
206 | return service_impl_.native_handle(impl); | |
207 | } | |
208 | ||
209 | /// Set a socket option. | |
210 | template <typename SettableSocketOption> | |
b32b8144 | 211 | BOOST_ASIO_SYNC_OP_VOID set_option(implementation_type& impl, |
7c673cae FG |
212 | const SettableSocketOption& option, boost::system::error_code& ec) |
213 | { | |
b32b8144 FG |
214 | service_impl_.set_option(impl, option, ec); |
215 | BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); | |
7c673cae FG |
216 | } |
217 | ||
218 | /// Get a socket option. | |
219 | template <typename GettableSocketOption> | |
b32b8144 | 220 | BOOST_ASIO_SYNC_OP_VOID get_option(const implementation_type& impl, |
7c673cae FG |
221 | GettableSocketOption& option, boost::system::error_code& ec) const |
222 | { | |
b32b8144 FG |
223 | service_impl_.get_option(impl, option, ec); |
224 | BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); | |
7c673cae FG |
225 | } |
226 | ||
227 | /// Perform an IO control command on the socket. | |
228 | template <typename IoControlCommand> | |
b32b8144 | 229 | BOOST_ASIO_SYNC_OP_VOID io_control(implementation_type& impl, |
7c673cae FG |
230 | IoControlCommand& command, boost::system::error_code& ec) |
231 | { | |
b32b8144 FG |
232 | service_impl_.io_control(impl, command, ec); |
233 | BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); | |
7c673cae FG |
234 | } |
235 | ||
236 | /// Gets the non-blocking mode of the acceptor. | |
237 | bool non_blocking(const implementation_type& impl) const | |
238 | { | |
239 | return service_impl_.non_blocking(impl); | |
240 | } | |
241 | ||
242 | /// Sets the non-blocking mode of the acceptor. | |
b32b8144 | 243 | BOOST_ASIO_SYNC_OP_VOID non_blocking(implementation_type& impl, |
7c673cae FG |
244 | bool mode, boost::system::error_code& ec) |
245 | { | |
b32b8144 FG |
246 | service_impl_.non_blocking(impl, mode, ec); |
247 | BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); | |
7c673cae FG |
248 | } |
249 | ||
250 | /// Gets the non-blocking mode of the native acceptor implementation. | |
251 | bool native_non_blocking(const implementation_type& impl) const | |
252 | { | |
253 | return service_impl_.native_non_blocking(impl); | |
254 | } | |
255 | ||
256 | /// Sets the non-blocking mode of the native acceptor implementation. | |
b32b8144 | 257 | BOOST_ASIO_SYNC_OP_VOID native_non_blocking(implementation_type& impl, |
7c673cae FG |
258 | bool mode, boost::system::error_code& ec) |
259 | { | |
b32b8144 FG |
260 | service_impl_.native_non_blocking(impl, mode, ec); |
261 | BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); | |
7c673cae FG |
262 | } |
263 | ||
264 | /// Get the local endpoint. | |
265 | endpoint_type local_endpoint(const implementation_type& impl, | |
266 | boost::system::error_code& ec) const | |
267 | { | |
268 | return service_impl_.local_endpoint(impl, ec); | |
269 | } | |
270 | ||
b32b8144 FG |
271 | /// Wait for the acceptor to become ready to read, ready to write, or to have |
272 | /// pending error conditions. | |
273 | BOOST_ASIO_SYNC_OP_VOID wait(implementation_type& impl, | |
274 | socket_base::wait_type w, boost::system::error_code& ec) | |
275 | { | |
276 | service_impl_.wait(impl, w, ec); | |
277 | BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); | |
278 | } | |
279 | ||
280 | /// Asynchronously wait for the acceptor to become ready to read, ready to | |
281 | /// write, or to have pending error conditions. | |
282 | template <typename WaitHandler> | |
283 | BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, | |
284 | void (boost::system::error_code)) | |
285 | async_wait(implementation_type& impl, socket_base::wait_type w, | |
286 | BOOST_ASIO_MOVE_ARG(WaitHandler) handler) | |
287 | { | |
288 | async_completion<WaitHandler, | |
289 | void (boost::system::error_code)> init(handler); | |
290 | ||
291 | service_impl_.async_wait(impl, w, init.completion_handler); | |
292 | ||
293 | return init.result.get(); | |
294 | } | |
295 | ||
7c673cae FG |
296 | /// Accept a new connection. |
297 | template <typename Protocol1, typename SocketService> | |
b32b8144 | 298 | BOOST_ASIO_SYNC_OP_VOID accept(implementation_type& impl, |
7c673cae FG |
299 | basic_socket<Protocol1, SocketService>& peer, |
300 | endpoint_type* peer_endpoint, boost::system::error_code& ec, | |
301 | typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0) | |
302 | { | |
b32b8144 FG |
303 | service_impl_.accept(impl, peer, peer_endpoint, ec); |
304 | BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); | |
305 | } | |
306 | ||
307 | #if defined(BOOST_ASIO_HAS_MOVE) | |
308 | /// Accept a new connection. | |
309 | typename Protocol::socket accept(implementation_type& impl, | |
310 | io_context* peer_io_context, endpoint_type* peer_endpoint, | |
311 | boost::system::error_code& ec) | |
312 | { | |
313 | return service_impl_.accept(impl, peer_io_context, peer_endpoint, ec); | |
7c673cae | 314 | } |
b32b8144 | 315 | #endif // defined(BOOST_ASIO_HAS_MOVE) |
7c673cae FG |
316 | |
317 | /// Start an asynchronous accept. | |
318 | template <typename Protocol1, typename SocketService, typename AcceptHandler> | |
319 | BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, | |
320 | void (boost::system::error_code)) | |
321 | async_accept(implementation_type& impl, | |
322 | basic_socket<Protocol1, SocketService>& peer, | |
323 | endpoint_type* peer_endpoint, | |
324 | BOOST_ASIO_MOVE_ARG(AcceptHandler) handler, | |
325 | typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0) | |
326 | { | |
b32b8144 FG |
327 | async_completion<AcceptHandler, |
328 | void (boost::system::error_code)> init(handler); | |
329 | ||
330 | service_impl_.async_accept(impl, | |
331 | peer, peer_endpoint, init.completion_handler); | |
332 | ||
333 | return init.result.get(); | |
334 | } | |
335 | ||
336 | #if defined(BOOST_ASIO_HAS_MOVE) | |
337 | /// Start an asynchronous accept. | |
338 | template <typename MoveAcceptHandler> | |
339 | BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, | |
340 | void (boost::system::error_code, typename Protocol::socket)) | |
341 | async_accept(implementation_type& impl, | |
342 | boost::asio::io_context* peer_io_context, endpoint_type* peer_endpoint, | |
343 | BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler) | |
344 | { | |
345 | async_completion<MoveAcceptHandler, | |
346 | void (boost::system::error_code, | |
347 | typename Protocol::socket)> init(handler); | |
7c673cae | 348 | |
b32b8144 FG |
349 | service_impl_.async_accept(impl, |
350 | peer_io_context, peer_endpoint, init.completion_handler); | |
7c673cae FG |
351 | |
352 | return init.result.get(); | |
353 | } | |
b32b8144 | 354 | #endif // defined(BOOST_ASIO_HAS_MOVE) |
7c673cae FG |
355 | |
356 | private: | |
357 | // Destroy all user-defined handler objects owned by the service. | |
b32b8144 | 358 | void shutdown() |
7c673cae | 359 | { |
b32b8144 | 360 | service_impl_.shutdown(); |
7c673cae FG |
361 | } |
362 | ||
363 | // The platform-specific implementation. | |
364 | service_impl_type service_impl_; | |
365 | }; | |
366 | ||
367 | } // namespace asio | |
368 | } // namespace boost | |
369 | ||
370 | #include <boost/asio/detail/pop_options.hpp> | |
371 | ||
b32b8144 FG |
372 | #endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) |
373 | ||
7c673cae | 374 | #endif // BOOST_ASIO_SOCKET_ACCEPTOR_SERVICE_HPP |