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