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 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> 19 #include <boost/asio/basic_socket.hpp> 20 #include <boost/asio/detail/type_traits.hpp> 21 #include <boost/asio/error.hpp> 22 #include <boost/asio/io_service.hpp> 23 24 #if defined(BOOST_ASIO_WINDOWS_RUNTIME) 25 # include <boost/asio/detail/null_socket_service.hpp> 26 #elif defined(BOOST_ASIO_HAS_IOCP) 27 # include <boost/asio/detail/win_iocp_socket_service.hpp> 28 #else 29 # include <boost/asio/detail/reactive_socket_service.hpp> 30 #endif 31 32 #include <boost/asio/detail/push_options.hpp> 33 34 namespace boost { 35 namespace asio { 36 37 /// Default service implementation for a socket acceptor. 38 template <typename Protocol> 39 class socket_acceptor_service 40 #if defined(GENERATING_DOCUMENTATION) 41 : public boost::asio::io_service::service 42 #else 43 : public boost::asio::detail::service_base<socket_acceptor_service<Protocol> > 44 #endif 45 { 46 public: 47 #if defined(GENERATING_DOCUMENTATION) 48 /// The unique service identifier. 49 static boost::asio::io_service::id id; 50 #endif 51 52 /// The protocol type. 53 typedef Protocol protocol_type; 54 55 /// The endpoint type. 56 typedef typename protocol_type::endpoint endpoint_type; 57 58 private: 59 // The type of the platform-specific implementation. 60 #if defined(BOOST_ASIO_WINDOWS_RUNTIME) 61 typedef detail::null_socket_service<Protocol> service_impl_type; 62 #elif defined(BOOST_ASIO_HAS_IOCP) 63 typedef detail::win_iocp_socket_service<Protocol> service_impl_type; 64 #else 65 typedef detail::reactive_socket_service<Protocol> service_impl_type; 66 #endif 67 68 public: 69 /// The native type of the socket acceptor. 70 #if defined(GENERATING_DOCUMENTATION) 71 typedef implementation_defined implementation_type; 72 #else 73 typedef typename service_impl_type::implementation_type implementation_type; 74 #endif 75 76 /// (Deprecated: Use native_handle_type.) The native acceptor type. 77 #if defined(GENERATING_DOCUMENTATION) 78 typedef implementation_defined native_type; 79 #else 80 typedef typename service_impl_type::native_handle_type native_type; 81 #endif 82 83 /// The native acceptor type. 84 #if defined(GENERATING_DOCUMENTATION) 85 typedef implementation_defined native_handle_type; 86 #else 87 typedef typename service_impl_type::native_handle_type native_handle_type; 88 #endif 89 90 /// Construct a new socket acceptor service for the specified io_service. socket_acceptor_service(boost::asio::io_service & io_service)91 explicit socket_acceptor_service(boost::asio::io_service& io_service) 92 : boost::asio::detail::service_base< 93 socket_acceptor_service<Protocol> >(io_service), 94 service_impl_(io_service) 95 { 96 } 97 98 /// Construct a new socket acceptor implementation. construct(implementation_type & impl)99 void construct(implementation_type& impl) 100 { 101 service_impl_.construct(impl); 102 } 103 104 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) 105 /// Move-construct a new socket acceptor implementation. move_construct(implementation_type & impl,implementation_type & other_impl)106 void move_construct(implementation_type& impl, 107 implementation_type& other_impl) 108 { 109 service_impl_.move_construct(impl, other_impl); 110 } 111 112 /// Move-assign from another socket acceptor implementation. move_assign(implementation_type & impl,socket_acceptor_service & other_service,implementation_type & other_impl)113 void move_assign(implementation_type& impl, 114 socket_acceptor_service& other_service, 115 implementation_type& other_impl) 116 { 117 service_impl_.move_assign(impl, other_service.service_impl_, other_impl); 118 } 119 120 /// Move-construct a new socket acceptor implementation from another protocol 121 /// type. 122 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)123 void converting_move_construct(implementation_type& impl, 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>( 130 impl, other_impl); 131 } 132 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) 133 134 /// Destroy a socket acceptor implementation. destroy(implementation_type & impl)135 void destroy(implementation_type& impl) 136 { 137 service_impl_.destroy(impl); 138 } 139 140 /// Open a new socket acceptor implementation. open(implementation_type & impl,const protocol_type & protocol,boost::system::error_code & ec)141 boost::system::error_code open(implementation_type& impl, 142 const protocol_type& protocol, boost::system::error_code& ec) 143 { 144 return service_impl_.open(impl, protocol, ec); 145 } 146 147 /// Assign an existing native acceptor to a socket acceptor. assign(implementation_type & impl,const protocol_type & protocol,const native_handle_type & native_acceptor,boost::system::error_code & ec)148 boost::system::error_code assign(implementation_type& impl, 149 const protocol_type& protocol, const native_handle_type& native_acceptor, 150 boost::system::error_code& ec) 151 { 152 return service_impl_.assign(impl, protocol, native_acceptor, ec); 153 } 154 155 /// Determine whether the acceptor is open. is_open(const implementation_type & impl) const156 bool is_open(const implementation_type& impl) const 157 { 158 return service_impl_.is_open(impl); 159 } 160 161 /// Cancel all asynchronous operations associated with the acceptor. cancel(implementation_type & impl,boost::system::error_code & ec)162 boost::system::error_code cancel(implementation_type& impl, 163 boost::system::error_code& ec) 164 { 165 return service_impl_.cancel(impl, ec); 166 } 167 168 /// Bind the socket acceptor to the specified local endpoint. bind(implementation_type & impl,const endpoint_type & endpoint,boost::system::error_code & ec)169 boost::system::error_code bind(implementation_type& impl, 170 const endpoint_type& endpoint, boost::system::error_code& ec) 171 { 172 return service_impl_.bind(impl, endpoint, ec); 173 } 174 175 /// Place the socket acceptor into the state where it will listen for new 176 /// connections. listen(implementation_type & impl,int backlog,boost::system::error_code & ec)177 boost::system::error_code listen(implementation_type& impl, int backlog, 178 boost::system::error_code& ec) 179 { 180 return service_impl_.listen(impl, backlog, ec); 181 } 182 183 /// Close a socket acceptor implementation. close(implementation_type & impl,boost::system::error_code & ec)184 boost::system::error_code close(implementation_type& impl, 185 boost::system::error_code& ec) 186 { 187 return service_impl_.close(impl, ec); 188 } 189 190 /// (Deprecated: Use native_handle().) Get the native acceptor implementation. native(implementation_type & impl)191 native_type native(implementation_type& impl) 192 { 193 return service_impl_.native_handle(impl); 194 } 195 196 /// Get the native acceptor implementation. native_handle(implementation_type & impl)197 native_handle_type native_handle(implementation_type& impl) 198 { 199 return service_impl_.native_handle(impl); 200 } 201 202 /// Set a socket option. 203 template <typename SettableSocketOption> set_option(implementation_type & impl,const SettableSocketOption & option,boost::system::error_code & ec)204 boost::system::error_code set_option(implementation_type& impl, 205 const SettableSocketOption& option, boost::system::error_code& ec) 206 { 207 return service_impl_.set_option(impl, option, ec); 208 } 209 210 /// Get a socket option. 211 template <typename GettableSocketOption> get_option(const implementation_type & impl,GettableSocketOption & option,boost::system::error_code & ec) const212 boost::system::error_code get_option(const implementation_type& impl, 213 GettableSocketOption& option, boost::system::error_code& ec) const 214 { 215 return service_impl_.get_option(impl, option, ec); 216 } 217 218 /// Perform an IO control command on the socket. 219 template <typename IoControlCommand> io_control(implementation_type & impl,IoControlCommand & command,boost::system::error_code & ec)220 boost::system::error_code io_control(implementation_type& impl, 221 IoControlCommand& command, boost::system::error_code& ec) 222 { 223 return service_impl_.io_control(impl, command, ec); 224 } 225 226 /// Gets the non-blocking mode of the acceptor. non_blocking(const implementation_type & impl) const227 bool non_blocking(const implementation_type& impl) const 228 { 229 return service_impl_.non_blocking(impl); 230 } 231 232 /// Sets the non-blocking mode of the acceptor. non_blocking(implementation_type & impl,bool mode,boost::system::error_code & ec)233 boost::system::error_code non_blocking(implementation_type& impl, 234 bool mode, boost::system::error_code& ec) 235 { 236 return service_impl_.non_blocking(impl, mode, ec); 237 } 238 239 /// Gets the non-blocking mode of the native acceptor implementation. native_non_blocking(const implementation_type & impl) const240 bool native_non_blocking(const implementation_type& impl) const 241 { 242 return service_impl_.native_non_blocking(impl); 243 } 244 245 /// Sets the non-blocking mode of the native acceptor implementation. native_non_blocking(implementation_type & impl,bool mode,boost::system::error_code & ec)246 boost::system::error_code native_non_blocking(implementation_type& impl, 247 bool mode, boost::system::error_code& ec) 248 { 249 return service_impl_.native_non_blocking(impl, mode, ec); 250 } 251 252 /// Get the local endpoint. local_endpoint(const implementation_type & impl,boost::system::error_code & ec) const253 endpoint_type local_endpoint(const implementation_type& impl, 254 boost::system::error_code& ec) const 255 { 256 return service_impl_.local_endpoint(impl, ec); 257 } 258 259 /// Accept a new connection. 260 template <typename Protocol1, typename SocketService> accept(implementation_type & impl,basic_socket<Protocol1,SocketService> & peer,endpoint_type * peer_endpoint,boost::system::error_code & ec,typename enable_if<is_convertible<Protocol,Protocol1>::value>::type * =0)261 boost::system::error_code accept(implementation_type& impl, 262 basic_socket<Protocol1, SocketService>& peer, 263 endpoint_type* peer_endpoint, boost::system::error_code& ec, 264 typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0) 265 { 266 return service_impl_.accept(impl, peer, peer_endpoint, ec); 267 } 268 269 /// Start an asynchronous accept. 270 template <typename Protocol1, typename SocketService, typename AcceptHandler> BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler,void (boost::system::error_code))271 BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, 272 void (boost::system::error_code)) 273 async_accept(implementation_type& impl, 274 basic_socket<Protocol1, SocketService>& peer, 275 endpoint_type* peer_endpoint, 276 BOOST_ASIO_MOVE_ARG(AcceptHandler) handler, 277 typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0) 278 { 279 detail::async_result_init< 280 AcceptHandler, void (boost::system::error_code)> init( 281 BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler)); 282 283 service_impl_.async_accept(impl, peer, peer_endpoint, init.handler); 284 285 return init.result.get(); 286 } 287 288 private: 289 // Destroy all user-defined handler objects owned by the service. shutdown_service()290 void shutdown_service() 291 { 292 service_impl_.shutdown_service(); 293 } 294 295 // The platform-specific implementation. 296 service_impl_type service_impl_; 297 }; 298 299 } // namespace asio 300 } // namespace boost 301 302 #include <boost/asio/detail/pop_options.hpp> 303 304 #endif // BOOST_ASIO_SOCKET_ACCEPTOR_SERVICE_HPP 305