1 //
2 // socket_acceptor_service.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
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 ASIO_SOCKET_ACCEPTOR_SERVICE_HPP
12 #define ASIO_SOCKET_ACCEPTOR_SERVICE_HPP
13 
14 
15 #include "asio/detail/config.hpp"
16 #include "asio/basic_socket.hpp"
17 #include "asio/detail/type_traits.hpp"
18 #include "asio/error.hpp"
19 #include "asio/io_service.hpp"
20 
21 # include "asio/detail/reactive_socket_service.hpp"
22 
23 #include "asio/detail/push_options.hpp"
24 
25 namespace asio {
26 
27 /// Default service implementation for a socket acceptor.
28 template <typename Protocol>
29 class socket_acceptor_service
30   : public asio::detail::service_base<socket_acceptor_service<Protocol> >
31 {
32 public:
33 
34   /// The protocol type.
35   typedef Protocol protocol_type;
36 
37   /// The endpoint type.
38   typedef typename protocol_type::endpoint endpoint_type;
39 
40 private:
41   // The type of the platform-specific implementation.
42   typedef detail::reactive_socket_service<Protocol> service_impl_type;
43 
44 public:
45   /// The native type of the socket acceptor.
46   typedef typename service_impl_type::implementation_type implementation_type;
47 
48   /// (Deprecated: Use native_handle_type.) The native acceptor type.
49   typedef typename service_impl_type::native_handle_type native_type;
50 
51   /// The native acceptor type.
52   typedef typename service_impl_type::native_handle_type native_handle_type;
53 
54   /// Construct a new socket acceptor service for the specified io_service.
socket_acceptor_service(asio::io_service & io_service)55   explicit socket_acceptor_service(asio::io_service& io_service)
56     : asio::detail::service_base<
57         socket_acceptor_service<Protocol> >(io_service),
58       service_impl_(io_service)
59   {
60   }
61 
62   /// Construct a new socket acceptor implementation.
construct(implementation_type & impl)63   void construct(implementation_type& impl)
64   {
65     service_impl_.construct(impl);
66   }
67 
68   /// Move-construct a new socket acceptor implementation.
move_construct(implementation_type & impl,implementation_type & other_impl)69   void move_construct(implementation_type& impl,
70       implementation_type& other_impl)
71   {
72     service_impl_.move_construct(impl, other_impl);
73   }
74 
75   /// Move-assign from another socket acceptor implementation.
move_assign(implementation_type & impl,socket_acceptor_service & other_service,implementation_type & other_impl)76   void move_assign(implementation_type& impl,
77       socket_acceptor_service& other_service,
78       implementation_type& other_impl)
79   {
80     service_impl_.move_assign(impl, other_service.service_impl_, other_impl);
81   }
82 
83   /// Move-construct a new socket acceptor implementation from another protocol
84   /// type.
85   template <typename Protocol1>
converting_move_construct(implementation_type & impl,typename socket_acceptor_service<Protocol1>::implementation_type & other_impl,typename enable_if<is_convertible<Protocol1,Protocol>::value>::type * =0)86   void converting_move_construct(implementation_type& impl,
87       typename socket_acceptor_service<
88         Protocol1>::implementation_type& other_impl,
89       typename enable_if<is_convertible<
90         Protocol1, Protocol>::value>::type* = 0)
91   {
92     service_impl_.template converting_move_construct<Protocol1>(
93         impl, other_impl);
94   }
95 
96   /// Destroy a socket acceptor implementation.
destroy(implementation_type & impl)97   void destroy(implementation_type& impl)
98   {
99     service_impl_.destroy(impl);
100   }
101 
102   /// Open a new socket acceptor implementation.
open(implementation_type & impl,const protocol_type & protocol,asio::error_code & ec)103   asio::error_code open(implementation_type& impl,
104       const protocol_type& protocol, asio::error_code& ec)
105   {
106     return service_impl_.open(impl, protocol, ec);
107   }
108 
109   /// Assign an existing native acceptor to a socket acceptor.
assign(implementation_type & impl,const protocol_type & protocol,const native_handle_type & native_acceptor,asio::error_code & ec)110   asio::error_code assign(implementation_type& impl,
111       const protocol_type& protocol, const native_handle_type& native_acceptor,
112       asio::error_code& ec)
113   {
114     return service_impl_.assign(impl, protocol, native_acceptor, ec);
115   }
116 
117   /// Determine whether the acceptor is open.
is_open(const implementation_type & impl) const118   bool is_open(const implementation_type& impl) const
119   {
120     return service_impl_.is_open(impl);
121   }
122 
123   /// Cancel all asynchronous operations associated with the acceptor.
cancel(implementation_type & impl,asio::error_code & ec)124   asio::error_code cancel(implementation_type& impl,
125       asio::error_code& ec)
126   {
127     return service_impl_.cancel(impl, ec);
128   }
129 
130   /// Bind the socket acceptor to the specified local endpoint.
bind(implementation_type & impl,const endpoint_type & endpoint,asio::error_code & ec)131   asio::error_code bind(implementation_type& impl,
132       const endpoint_type& endpoint, asio::error_code& ec)
133   {
134     return service_impl_.bind(impl, endpoint, ec);
135   }
136 
137   /// Place the socket acceptor into the state where it will listen for new
138   /// connections.
listen(implementation_type & impl,int backlog,asio::error_code & ec)139   asio::error_code listen(implementation_type& impl, int backlog,
140       asio::error_code& ec)
141   {
142     return service_impl_.listen(impl, backlog, ec);
143   }
144 
145   /// Close a socket acceptor implementation.
close(implementation_type & impl,asio::error_code & ec)146   asio::error_code close(implementation_type& impl,
147       asio::error_code& ec)
148   {
149     return service_impl_.close(impl, ec);
150   }
151 
152   /// (Deprecated: Use native_handle().) Get the native acceptor implementation.
native(implementation_type & impl)153   native_type native(implementation_type& impl)
154   {
155     return service_impl_.native_handle(impl);
156   }
157 
158   /// Get the native acceptor implementation.
native_handle(implementation_type & impl)159   native_handle_type native_handle(implementation_type& impl)
160   {
161     return service_impl_.native_handle(impl);
162   }
163 
164   /// Set a socket option.
165   template <typename SettableSocketOption>
set_option(implementation_type & impl,const SettableSocketOption & option,asio::error_code & ec)166   asio::error_code set_option(implementation_type& impl,
167       const SettableSocketOption& option, asio::error_code& ec)
168   {
169     return service_impl_.set_option(impl, option, ec);
170   }
171 
172   /// Get a socket option.
173   template <typename GettableSocketOption>
get_option(const implementation_type & impl,GettableSocketOption & option,asio::error_code & ec) const174   asio::error_code get_option(const implementation_type& impl,
175       GettableSocketOption& option, asio::error_code& ec) const
176   {
177     return service_impl_.get_option(impl, option, ec);
178   }
179 
180   /// Perform an IO control command on the socket.
181   template <typename IoControlCommand>
io_control(implementation_type & impl,IoControlCommand & command,asio::error_code & ec)182   asio::error_code io_control(implementation_type& impl,
183       IoControlCommand& command, asio::error_code& ec)
184   {
185     return service_impl_.io_control(impl, command, ec);
186   }
187 
188   /// Gets the non-blocking mode of the acceptor.
non_blocking(const implementation_type & impl) const189   bool non_blocking(const implementation_type& impl) const
190   {
191     return service_impl_.non_blocking(impl);
192   }
193 
194   /// Sets the non-blocking mode of the acceptor.
non_blocking(implementation_type & impl,bool mode,asio::error_code & ec)195   asio::error_code non_blocking(implementation_type& impl,
196       bool mode, asio::error_code& ec)
197   {
198     return service_impl_.non_blocking(impl, mode, ec);
199   }
200 
201   /// Gets the non-blocking mode of the native acceptor implementation.
native_non_blocking(const implementation_type & impl) const202   bool native_non_blocking(const implementation_type& impl) const
203   {
204     return service_impl_.native_non_blocking(impl);
205   }
206 
207   /// Sets the non-blocking mode of the native acceptor implementation.
native_non_blocking(implementation_type & impl,bool mode,asio::error_code & ec)208   asio::error_code native_non_blocking(implementation_type& impl,
209       bool mode, asio::error_code& ec)
210   {
211     return service_impl_.native_non_blocking(impl, mode, ec);
212   }
213 
214   /// Get the local endpoint.
local_endpoint(const implementation_type & impl,asio::error_code & ec) const215   endpoint_type local_endpoint(const implementation_type& impl,
216       asio::error_code& ec) const
217   {
218     return service_impl_.local_endpoint(impl, ec);
219   }
220 
221   /// Accept a new connection.
222   template <typename Protocol1, typename SocketService>
accept(implementation_type & impl,basic_socket<Protocol1,SocketService> & peer,endpoint_type * peer_endpoint,asio::error_code & ec,typename enable_if<is_convertible<Protocol,Protocol1>::value>::type * =0)223   asio::error_code accept(implementation_type& impl,
224       basic_socket<Protocol1, SocketService>& peer,
225       endpoint_type* peer_endpoint, asio::error_code& ec,
226       typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
227   {
228     return service_impl_.accept(impl, peer, peer_endpoint, ec);
229   }
230 
231   /// Start an asynchronous accept.
232   template <typename Protocol1, typename SocketService, typename AcceptHandler>
ASIO_INITFN_RESULT_TYPE(AcceptHandler,void (asio::error_code))233   ASIO_INITFN_RESULT_TYPE(AcceptHandler,
234       void (asio::error_code))
235   async_accept(implementation_type& impl,
236       basic_socket<Protocol1, SocketService>& peer,
237       endpoint_type* peer_endpoint,
238       ASIO_MOVE_ARG(AcceptHandler) handler,
239       typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
240   {
241     detail::async_result_init<
242       AcceptHandler, void (asio::error_code)> init(
243         ASIO_MOVE_CAST(AcceptHandler)(handler));
244 
245     service_impl_.async_accept(impl, peer, peer_endpoint, init.handler);
246 
247     return init.result.get();
248   }
249 
250 private:
251   // Destroy all user-defined handler objects owned by the service.
shutdown_service()252   void shutdown_service()
253   {
254     service_impl_.shutdown_service();
255   }
256 
257   // The platform-specific implementation.
258   service_impl_type service_impl_;
259 };
260 
261 } // namespace asio
262 
263 #include "asio/detail/pop_options.hpp"
264 
265 #endif // ASIO_SOCKET_ACCEPTOR_SERVICE_HPP
266