|
||||
File indexing completed on 2025-01-30 09:33:41
0001 // 0002 // basic_socket_acceptor.hpp 0003 // ~~~~~~~~~~~~~~~~~~~~~~~~~ 0004 // 0005 // Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) 0006 // 0007 // Distributed under the Boost Software License, Version 1.0. (See accompanying 0008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 0009 // 0010 0011 #ifndef BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_HPP 0012 #define BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_HPP 0013 0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 0015 # pragma once 0016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 0017 0018 #include <utility> 0019 #include <boost/asio/detail/config.hpp> 0020 #include <boost/asio/any_io_executor.hpp> 0021 #include <boost/asio/basic_socket.hpp> 0022 #include <boost/asio/detail/handler_type_requirements.hpp> 0023 #include <boost/asio/detail/io_object_impl.hpp> 0024 #include <boost/asio/detail/non_const_lvalue.hpp> 0025 #include <boost/asio/detail/throw_error.hpp> 0026 #include <boost/asio/detail/type_traits.hpp> 0027 #include <boost/asio/error.hpp> 0028 #include <boost/asio/execution_context.hpp> 0029 #include <boost/asio/socket_base.hpp> 0030 0031 #if defined(BOOST_ASIO_WINDOWS_RUNTIME) 0032 # include <boost/asio/detail/null_socket_service.hpp> 0033 #elif defined(BOOST_ASIO_HAS_IOCP) 0034 # include <boost/asio/detail/win_iocp_socket_service.hpp> 0035 #elif defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT) 0036 # include <boost/asio/detail/io_uring_socket_service.hpp> 0037 #else 0038 # include <boost/asio/detail/reactive_socket_service.hpp> 0039 #endif 0040 0041 #include <boost/asio/detail/push_options.hpp> 0042 0043 namespace boost { 0044 namespace asio { 0045 0046 #if !defined(BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL) 0047 #define BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL 0048 0049 // Forward declaration with defaulted arguments. 0050 template <typename Protocol, typename Executor = any_io_executor> 0051 class basic_socket_acceptor; 0052 0053 #endif // !defined(BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL) 0054 0055 /// Provides the ability to accept new connections. 0056 /** 0057 * The basic_socket_acceptor class template is used for accepting new socket 0058 * connections. 0059 * 0060 * @par Thread Safety 0061 * @e Distinct @e objects: Safe.@n 0062 * @e Shared @e objects: Unsafe. 0063 * 0064 * Synchronous @c accept operations are thread safe, if the underlying 0065 * operating system calls are also thread safe. This means that it is permitted 0066 * to perform concurrent calls to synchronous @c accept operations on a single 0067 * socket object. Other synchronous operations, such as @c open or @c close, are 0068 * not thread safe. 0069 * 0070 * @par Example 0071 * Opening a socket acceptor with the SO_REUSEADDR option enabled: 0072 * @code 0073 * boost::asio::ip::tcp::acceptor acceptor(my_context); 0074 * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), port); 0075 * acceptor.open(endpoint.protocol()); 0076 * acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); 0077 * acceptor.bind(endpoint); 0078 * acceptor.listen(); 0079 * @endcode 0080 */ 0081 template <typename Protocol, typename Executor> 0082 class basic_socket_acceptor 0083 : public socket_base 0084 { 0085 private: 0086 class initiate_async_wait; 0087 class initiate_async_accept; 0088 class initiate_async_move_accept; 0089 0090 public: 0091 /// The type of the executor associated with the object. 0092 typedef Executor executor_type; 0093 0094 /// Rebinds the acceptor type to another executor. 0095 template <typename Executor1> 0096 struct rebind_executor 0097 { 0098 /// The socket type when rebound to the specified executor. 0099 typedef basic_socket_acceptor<Protocol, Executor1> other; 0100 }; 0101 0102 /// The native representation of an acceptor. 0103 #if defined(GENERATING_DOCUMENTATION) 0104 typedef implementation_defined native_handle_type; 0105 #elif defined(BOOST_ASIO_WINDOWS_RUNTIME) 0106 typedef typename detail::null_socket_service< 0107 Protocol>::native_handle_type native_handle_type; 0108 #elif defined(BOOST_ASIO_HAS_IOCP) 0109 typedef typename detail::win_iocp_socket_service< 0110 Protocol>::native_handle_type native_handle_type; 0111 #elif defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT) 0112 typedef typename detail::io_uring_socket_service< 0113 Protocol>::native_handle_type native_handle_type; 0114 #else 0115 typedef typename detail::reactive_socket_service< 0116 Protocol>::native_handle_type native_handle_type; 0117 #endif 0118 0119 /// The protocol type. 0120 typedef Protocol protocol_type; 0121 0122 /// The endpoint type. 0123 typedef typename Protocol::endpoint endpoint_type; 0124 0125 /// Construct an acceptor without opening it. 0126 /** 0127 * This constructor creates an acceptor without opening it to listen for new 0128 * connections. The open() function must be called before the acceptor can 0129 * accept new socket connections. 0130 * 0131 * @param ex The I/O executor that the acceptor will use, by default, to 0132 * dispatch handlers for any asynchronous operations performed on the 0133 * acceptor. 0134 */ 0135 explicit basic_socket_acceptor(const executor_type& ex) 0136 : impl_(0, ex) 0137 { 0138 } 0139 0140 /// Construct an acceptor without opening it. 0141 /** 0142 * This constructor creates an acceptor without opening it to listen for new 0143 * connections. The open() function must be called before the acceptor can 0144 * accept new socket connections. 0145 * 0146 * @param context An execution context which provides the I/O executor that 0147 * the acceptor will use, by default, to dispatch handlers for any 0148 * asynchronous operations performed on the acceptor. 0149 */ 0150 template <typename ExecutionContext> 0151 explicit basic_socket_acceptor(ExecutionContext& context, 0152 constraint_t< 0153 is_convertible<ExecutionContext&, execution_context&>::value 0154 > = 0) 0155 : impl_(0, 0, context) 0156 { 0157 } 0158 0159 /// Construct an open acceptor. 0160 /** 0161 * This constructor creates an acceptor and automatically opens it. 0162 * 0163 * @param ex The I/O executor that the acceptor will use, by default, to 0164 * dispatch handlers for any asynchronous operations performed on the 0165 * acceptor. 0166 * 0167 * @param protocol An object specifying protocol parameters to be used. 0168 * 0169 * @throws boost::system::system_error Thrown on failure. 0170 */ 0171 basic_socket_acceptor(const executor_type& ex, const protocol_type& protocol) 0172 : impl_(0, ex) 0173 { 0174 boost::system::error_code ec; 0175 impl_.get_service().open(impl_.get_implementation(), protocol, ec); 0176 boost::asio::detail::throw_error(ec, "open"); 0177 } 0178 0179 /// Construct an open acceptor. 0180 /** 0181 * This constructor creates an acceptor and automatically opens it. 0182 * 0183 * @param context An execution context which provides the I/O executor that 0184 * the acceptor will use, by default, to dispatch handlers for any 0185 * asynchronous operations performed on the acceptor. 0186 * 0187 * @param protocol An object specifying protocol parameters to be used. 0188 * 0189 * @throws boost::system::system_error Thrown on failure. 0190 */ 0191 template <typename ExecutionContext> 0192 basic_socket_acceptor(ExecutionContext& context, 0193 const protocol_type& protocol, 0194 constraint_t< 0195 is_convertible<ExecutionContext&, execution_context&>::value, 0196 defaulted_constraint 0197 > = defaulted_constraint()) 0198 : impl_(0, 0, context) 0199 { 0200 boost::system::error_code ec; 0201 impl_.get_service().open(impl_.get_implementation(), protocol, ec); 0202 boost::asio::detail::throw_error(ec, "open"); 0203 } 0204 0205 /// Construct an acceptor opened on the given endpoint. 0206 /** 0207 * This constructor creates an acceptor and automatically opens it to listen 0208 * for new connections on the specified endpoint. 0209 * 0210 * @param ex The I/O executor that the acceptor will use, by default, to 0211 * dispatch handlers for any asynchronous operations performed on the 0212 * acceptor. 0213 * 0214 * @param endpoint An endpoint on the local machine on which the acceptor 0215 * will listen for new connections. 0216 * 0217 * @param reuse_addr Whether the constructor should set the socket option 0218 * socket_base::reuse_address. 0219 * 0220 * @throws boost::system::system_error Thrown on failure. 0221 * 0222 * @note This constructor is equivalent to the following code: 0223 * @code 0224 * basic_socket_acceptor<Protocol> acceptor(my_context); 0225 * acceptor.open(endpoint.protocol()); 0226 * if (reuse_addr) 0227 * acceptor.set_option(socket_base::reuse_address(true)); 0228 * acceptor.bind(endpoint); 0229 * acceptor.listen(); 0230 * @endcode 0231 */ 0232 basic_socket_acceptor(const executor_type& ex, 0233 const endpoint_type& endpoint, bool reuse_addr = true) 0234 : impl_(0, ex) 0235 { 0236 boost::system::error_code ec; 0237 const protocol_type protocol = endpoint.protocol(); 0238 impl_.get_service().open(impl_.get_implementation(), protocol, ec); 0239 boost::asio::detail::throw_error(ec, "open"); 0240 if (reuse_addr) 0241 { 0242 impl_.get_service().set_option(impl_.get_implementation(), 0243 socket_base::reuse_address(true), ec); 0244 boost::asio::detail::throw_error(ec, "set_option"); 0245 } 0246 impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); 0247 boost::asio::detail::throw_error(ec, "bind"); 0248 impl_.get_service().listen(impl_.get_implementation(), 0249 socket_base::max_listen_connections, ec); 0250 boost::asio::detail::throw_error(ec, "listen"); 0251 } 0252 0253 /// Construct an acceptor opened on the given endpoint. 0254 /** 0255 * This constructor creates an acceptor and automatically opens it to listen 0256 * for new connections on the specified endpoint. 0257 * 0258 * @param context An execution context which provides the I/O executor that 0259 * the acceptor will use, by default, to dispatch handlers for any 0260 * asynchronous operations performed on the acceptor. 0261 * 0262 * @param endpoint An endpoint on the local machine on which the acceptor 0263 * will listen for new connections. 0264 * 0265 * @param reuse_addr Whether the constructor should set the socket option 0266 * socket_base::reuse_address. 0267 * 0268 * @throws boost::system::system_error Thrown on failure. 0269 * 0270 * @note This constructor is equivalent to the following code: 0271 * @code 0272 * basic_socket_acceptor<Protocol> acceptor(my_context); 0273 * acceptor.open(endpoint.protocol()); 0274 * if (reuse_addr) 0275 * acceptor.set_option(socket_base::reuse_address(true)); 0276 * acceptor.bind(endpoint); 0277 * acceptor.listen(); 0278 * @endcode 0279 */ 0280 template <typename ExecutionContext> 0281 basic_socket_acceptor(ExecutionContext& context, 0282 const endpoint_type& endpoint, bool reuse_addr = true, 0283 constraint_t< 0284 is_convertible<ExecutionContext&, execution_context&>::value 0285 > = 0) 0286 : impl_(0, 0, context) 0287 { 0288 boost::system::error_code ec; 0289 const protocol_type protocol = endpoint.protocol(); 0290 impl_.get_service().open(impl_.get_implementation(), protocol, ec); 0291 boost::asio::detail::throw_error(ec, "open"); 0292 if (reuse_addr) 0293 { 0294 impl_.get_service().set_option(impl_.get_implementation(), 0295 socket_base::reuse_address(true), ec); 0296 boost::asio::detail::throw_error(ec, "set_option"); 0297 } 0298 impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); 0299 boost::asio::detail::throw_error(ec, "bind"); 0300 impl_.get_service().listen(impl_.get_implementation(), 0301 socket_base::max_listen_connections, ec); 0302 boost::asio::detail::throw_error(ec, "listen"); 0303 } 0304 0305 /// Construct a basic_socket_acceptor on an existing native acceptor. 0306 /** 0307 * This constructor creates an acceptor object to hold an existing native 0308 * acceptor. 0309 * 0310 * @param ex The I/O executor that the acceptor will use, by default, to 0311 * dispatch handlers for any asynchronous operations performed on the 0312 * acceptor. 0313 * 0314 * @param protocol An object specifying protocol parameters to be used. 0315 * 0316 * @param native_acceptor A native acceptor. 0317 * 0318 * @throws boost::system::system_error Thrown on failure. 0319 */ 0320 basic_socket_acceptor(const executor_type& ex, 0321 const protocol_type& protocol, const native_handle_type& native_acceptor) 0322 : impl_(0, ex) 0323 { 0324 boost::system::error_code ec; 0325 impl_.get_service().assign(impl_.get_implementation(), 0326 protocol, native_acceptor, ec); 0327 boost::asio::detail::throw_error(ec, "assign"); 0328 } 0329 0330 /// Construct a basic_socket_acceptor on an existing native acceptor. 0331 /** 0332 * This constructor creates an acceptor object to hold an existing native 0333 * acceptor. 0334 * 0335 * @param context An execution context which provides the I/O executor that 0336 * the acceptor will use, by default, to dispatch handlers for any 0337 * asynchronous operations performed on the acceptor. 0338 * 0339 * @param protocol An object specifying protocol parameters to be used. 0340 * 0341 * @param native_acceptor A native acceptor. 0342 * 0343 * @throws boost::system::system_error Thrown on failure. 0344 */ 0345 template <typename ExecutionContext> 0346 basic_socket_acceptor(ExecutionContext& context, 0347 const protocol_type& protocol, const native_handle_type& native_acceptor, 0348 constraint_t< 0349 is_convertible<ExecutionContext&, execution_context&>::value 0350 > = 0) 0351 : impl_(0, 0, context) 0352 { 0353 boost::system::error_code ec; 0354 impl_.get_service().assign(impl_.get_implementation(), 0355 protocol, native_acceptor, ec); 0356 boost::asio::detail::throw_error(ec, "assign"); 0357 } 0358 0359 /// Move-construct a basic_socket_acceptor from another. 0360 /** 0361 * This constructor moves an acceptor from one object to another. 0362 * 0363 * @param other The other basic_socket_acceptor object from which the move 0364 * will occur. 0365 * 0366 * @note Following the move, the moved-from object is in the same state as if 0367 * constructed using the @c basic_socket_acceptor(const executor_type&) 0368 * constructor. 0369 */ 0370 basic_socket_acceptor(basic_socket_acceptor&& other) noexcept 0371 : impl_(std::move(other.impl_)) 0372 { 0373 } 0374 0375 /// Move-assign a basic_socket_acceptor from another. 0376 /** 0377 * This assignment operator moves an acceptor from one object to another. 0378 * 0379 * @param other The other basic_socket_acceptor object from which the move 0380 * will occur. 0381 * 0382 * @note Following the move, the moved-from object is in the same state as if 0383 * constructed using the @c basic_socket_acceptor(const executor_type&) 0384 * constructor. 0385 */ 0386 basic_socket_acceptor& operator=(basic_socket_acceptor&& other) 0387 { 0388 impl_ = std::move(other.impl_); 0389 return *this; 0390 } 0391 0392 // All socket acceptors have access to each other's implementations. 0393 template <typename Protocol1, typename Executor1> 0394 friend class basic_socket_acceptor; 0395 0396 /// Move-construct a basic_socket_acceptor from an acceptor of another 0397 /// protocol type. 0398 /** 0399 * This constructor moves an acceptor from one object to another. 0400 * 0401 * @param other The other basic_socket_acceptor object from which the move 0402 * will occur. 0403 * 0404 * @note Following the move, the moved-from object is in the same state as if 0405 * constructed using the @c basic_socket_acceptor(const executor_type&) 0406 * constructor. 0407 */ 0408 template <typename Protocol1, typename Executor1> 0409 basic_socket_acceptor(basic_socket_acceptor<Protocol1, Executor1>&& other, 0410 constraint_t< 0411 is_convertible<Protocol1, Protocol>::value 0412 && is_convertible<Executor1, Executor>::value 0413 > = 0) 0414 : impl_(std::move(other.impl_)) 0415 { 0416 } 0417 0418 /// Move-assign a basic_socket_acceptor from an acceptor of another protocol 0419 /// type. 0420 /** 0421 * This assignment operator moves an acceptor from one object to another. 0422 * 0423 * @param other The other basic_socket_acceptor object from which the move 0424 * will occur. 0425 * 0426 * @note Following the move, the moved-from object is in the same state as if 0427 * constructed using the @c basic_socket_acceptor(const executor_type&) 0428 * constructor. 0429 */ 0430 template <typename Protocol1, typename Executor1> 0431 constraint_t< 0432 is_convertible<Protocol1, Protocol>::value 0433 && is_convertible<Executor1, Executor>::value, 0434 basic_socket_acceptor& 0435 > operator=(basic_socket_acceptor<Protocol1, Executor1>&& other) 0436 { 0437 basic_socket_acceptor tmp(std::move(other)); 0438 impl_ = std::move(tmp.impl_); 0439 return *this; 0440 } 0441 0442 /// Destroys the acceptor. 0443 /** 0444 * This function destroys the acceptor, cancelling any outstanding 0445 * asynchronous operations associated with the acceptor as if by calling 0446 * @c cancel. 0447 */ 0448 ~basic_socket_acceptor() 0449 { 0450 } 0451 0452 /// Get the executor associated with the object. 0453 const executor_type& get_executor() noexcept 0454 { 0455 return impl_.get_executor(); 0456 } 0457 0458 /// Open the acceptor using the specified protocol. 0459 /** 0460 * This function opens the socket acceptor so that it will use the specified 0461 * protocol. 0462 * 0463 * @param protocol An object specifying which protocol is to be used. 0464 * 0465 * @throws boost::system::system_error Thrown on failure. 0466 * 0467 * @par Example 0468 * @code 0469 * boost::asio::ip::tcp::acceptor acceptor(my_context); 0470 * acceptor.open(boost::asio::ip::tcp::v4()); 0471 * @endcode 0472 */ 0473 void open(const protocol_type& protocol = protocol_type()) 0474 { 0475 boost::system::error_code ec; 0476 impl_.get_service().open(impl_.get_implementation(), protocol, ec); 0477 boost::asio::detail::throw_error(ec, "open"); 0478 } 0479 0480 /// Open the acceptor using the specified protocol. 0481 /** 0482 * This function opens the socket acceptor so that it will use the specified 0483 * protocol. 0484 * 0485 * @param protocol An object specifying which protocol is to be used. 0486 * 0487 * @param ec Set to indicate what error occurred, if any. 0488 * 0489 * @par Example 0490 * @code 0491 * boost::asio::ip::tcp::acceptor acceptor(my_context); 0492 * boost::system::error_code ec; 0493 * acceptor.open(boost::asio::ip::tcp::v4(), ec); 0494 * if (ec) 0495 * { 0496 * // An error occurred. 0497 * } 0498 * @endcode 0499 */ 0500 BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol, 0501 boost::system::error_code& ec) 0502 { 0503 impl_.get_service().open(impl_.get_implementation(), protocol, ec); 0504 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 0505 } 0506 0507 /// Assigns an existing native acceptor to the acceptor. 0508 /* 0509 * This function opens the acceptor to hold an existing native acceptor. 0510 * 0511 * @param protocol An object specifying which protocol is to be used. 0512 * 0513 * @param native_acceptor A native acceptor. 0514 * 0515 * @throws boost::system::system_error Thrown on failure. 0516 */ 0517 void assign(const protocol_type& protocol, 0518 const native_handle_type& native_acceptor) 0519 { 0520 boost::system::error_code ec; 0521 impl_.get_service().assign(impl_.get_implementation(), 0522 protocol, native_acceptor, ec); 0523 boost::asio::detail::throw_error(ec, "assign"); 0524 } 0525 0526 /// Assigns an existing native acceptor to the acceptor. 0527 /* 0528 * This function opens the acceptor to hold an existing native acceptor. 0529 * 0530 * @param protocol An object specifying which protocol is to be used. 0531 * 0532 * @param native_acceptor A native acceptor. 0533 * 0534 * @param ec Set to indicate what error occurred, if any. 0535 */ 0536 BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol, 0537 const native_handle_type& native_acceptor, boost::system::error_code& ec) 0538 { 0539 impl_.get_service().assign(impl_.get_implementation(), 0540 protocol, native_acceptor, ec); 0541 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 0542 } 0543 0544 /// Determine whether the acceptor is open. 0545 bool is_open() const 0546 { 0547 return impl_.get_service().is_open(impl_.get_implementation()); 0548 } 0549 0550 /// Bind the acceptor to the given local endpoint. 0551 /** 0552 * This function binds the socket acceptor to the specified endpoint on the 0553 * local machine. 0554 * 0555 * @param endpoint An endpoint on the local machine to which the socket 0556 * acceptor will be bound. 0557 * 0558 * @throws boost::system::system_error Thrown on failure. 0559 * 0560 * @par Example 0561 * @code 0562 * boost::asio::ip::tcp::acceptor acceptor(my_context); 0563 * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345); 0564 * acceptor.open(endpoint.protocol()); 0565 * acceptor.bind(endpoint); 0566 * @endcode 0567 */ 0568 void bind(const endpoint_type& endpoint) 0569 { 0570 boost::system::error_code ec; 0571 impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); 0572 boost::asio::detail::throw_error(ec, "bind"); 0573 } 0574 0575 /// Bind the acceptor to the given local endpoint. 0576 /** 0577 * This function binds the socket acceptor to the specified endpoint on the 0578 * local machine. 0579 * 0580 * @param endpoint An endpoint on the local machine to which the socket 0581 * acceptor will be bound. 0582 * 0583 * @param ec Set to indicate what error occurred, if any. 0584 * 0585 * @par Example 0586 * @code 0587 * boost::asio::ip::tcp::acceptor acceptor(my_context); 0588 * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345); 0589 * acceptor.open(endpoint.protocol()); 0590 * boost::system::error_code ec; 0591 * acceptor.bind(endpoint, ec); 0592 * if (ec) 0593 * { 0594 * // An error occurred. 0595 * } 0596 * @endcode 0597 */ 0598 BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint, 0599 boost::system::error_code& ec) 0600 { 0601 impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); 0602 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 0603 } 0604 0605 /// Place the acceptor into the state where it will listen for new 0606 /// connections. 0607 /** 0608 * This function puts the socket acceptor into the state where it may accept 0609 * new connections. 0610 * 0611 * @param backlog The maximum length of the queue of pending connections. 0612 * 0613 * @throws boost::system::system_error Thrown on failure. 0614 */ 0615 void listen(int backlog = socket_base::max_listen_connections) 0616 { 0617 boost::system::error_code ec; 0618 impl_.get_service().listen(impl_.get_implementation(), backlog, ec); 0619 boost::asio::detail::throw_error(ec, "listen"); 0620 } 0621 0622 /// Place the acceptor into the state where it will listen for new 0623 /// connections. 0624 /** 0625 * This function puts the socket acceptor into the state where it may accept 0626 * new connections. 0627 * 0628 * @param backlog The maximum length of the queue of pending connections. 0629 * 0630 * @param ec Set to indicate what error occurred, if any. 0631 * 0632 * @par Example 0633 * @code 0634 * boost::asio::ip::tcp::acceptor acceptor(my_context); 0635 * ... 0636 * boost::system::error_code ec; 0637 * acceptor.listen(boost::asio::socket_base::max_listen_connections, ec); 0638 * if (ec) 0639 * { 0640 * // An error occurred. 0641 * } 0642 * @endcode 0643 */ 0644 BOOST_ASIO_SYNC_OP_VOID listen(int backlog, boost::system::error_code& ec) 0645 { 0646 impl_.get_service().listen(impl_.get_implementation(), backlog, ec); 0647 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 0648 } 0649 0650 /// Close the acceptor. 0651 /** 0652 * This function is used to close the acceptor. Any asynchronous accept 0653 * operations will be cancelled immediately. 0654 * 0655 * A subsequent call to open() is required before the acceptor can again be 0656 * used to again perform socket accept operations. 0657 * 0658 * @throws boost::system::system_error Thrown on failure. 0659 */ 0660 void close() 0661 { 0662 boost::system::error_code ec; 0663 impl_.get_service().close(impl_.get_implementation(), ec); 0664 boost::asio::detail::throw_error(ec, "close"); 0665 } 0666 0667 /// Close the acceptor. 0668 /** 0669 * This function is used to close the acceptor. Any asynchronous accept 0670 * operations will be cancelled immediately. 0671 * 0672 * A subsequent call to open() is required before the acceptor can again be 0673 * used to again perform socket accept operations. 0674 * 0675 * @param ec Set to indicate what error occurred, if any. 0676 * 0677 * @par Example 0678 * @code 0679 * boost::asio::ip::tcp::acceptor acceptor(my_context); 0680 * ... 0681 * boost::system::error_code ec; 0682 * acceptor.close(ec); 0683 * if (ec) 0684 * { 0685 * // An error occurred. 0686 * } 0687 * @endcode 0688 */ 0689 BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec) 0690 { 0691 impl_.get_service().close(impl_.get_implementation(), ec); 0692 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 0693 } 0694 0695 /// Release ownership of the underlying native acceptor. 0696 /** 0697 * This function causes all outstanding asynchronous accept operations to 0698 * finish immediately, and the handlers for cancelled operations will be 0699 * passed the boost::asio::error::operation_aborted error. Ownership of the 0700 * native acceptor is then transferred to the caller. 0701 * 0702 * @throws boost::system::system_error Thrown on failure. 0703 * 0704 * @note This function is unsupported on Windows versions prior to Windows 0705 * 8.1, and will fail with boost::asio::error::operation_not_supported on 0706 * these platforms. 0707 */ 0708 #if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ 0709 && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) 0710 __declspec(deprecated("This function always fails with " 0711 "operation_not_supported when used on Windows versions " 0712 "prior to Windows 8.1.")) 0713 #endif 0714 native_handle_type release() 0715 { 0716 boost::system::error_code ec; 0717 native_handle_type s = impl_.get_service().release( 0718 impl_.get_implementation(), ec); 0719 boost::asio::detail::throw_error(ec, "release"); 0720 return s; 0721 } 0722 0723 /// Release ownership of the underlying native acceptor. 0724 /** 0725 * This function causes all outstanding asynchronous accept operations to 0726 * finish immediately, and the handlers for cancelled operations will be 0727 * passed the boost::asio::error::operation_aborted error. Ownership of the 0728 * native acceptor is then transferred to the caller. 0729 * 0730 * @param ec Set to indicate what error occurred, if any. 0731 * 0732 * @note This function is unsupported on Windows versions prior to Windows 0733 * 8.1, and will fail with boost::asio::error::operation_not_supported on 0734 * these platforms. 0735 */ 0736 #if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ 0737 && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) 0738 __declspec(deprecated("This function always fails with " 0739 "operation_not_supported when used on Windows versions " 0740 "prior to Windows 8.1.")) 0741 #endif 0742 native_handle_type release(boost::system::error_code& ec) 0743 { 0744 return impl_.get_service().release(impl_.get_implementation(), ec); 0745 } 0746 0747 /// Get the native acceptor representation. 0748 /** 0749 * This function may be used to obtain the underlying representation of the 0750 * acceptor. This is intended to allow access to native acceptor functionality 0751 * that is not otherwise provided. 0752 */ 0753 native_handle_type native_handle() 0754 { 0755 return impl_.get_service().native_handle(impl_.get_implementation()); 0756 } 0757 0758 /// Cancel all asynchronous operations associated with the acceptor. 0759 /** 0760 * This function causes all outstanding asynchronous connect, send and receive 0761 * operations to finish immediately, and the handlers for cancelled operations 0762 * will be passed the boost::asio::error::operation_aborted error. 0763 * 0764 * @throws boost::system::system_error Thrown on failure. 0765 */ 0766 void cancel() 0767 { 0768 boost::system::error_code ec; 0769 impl_.get_service().cancel(impl_.get_implementation(), ec); 0770 boost::asio::detail::throw_error(ec, "cancel"); 0771 } 0772 0773 /// Cancel all asynchronous operations associated with the acceptor. 0774 /** 0775 * This function causes all outstanding asynchronous connect, send and receive 0776 * operations to finish immediately, and the handlers for cancelled operations 0777 * will be passed the boost::asio::error::operation_aborted error. 0778 * 0779 * @param ec Set to indicate what error occurred, if any. 0780 */ 0781 BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) 0782 { 0783 impl_.get_service().cancel(impl_.get_implementation(), ec); 0784 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 0785 } 0786 0787 /// Set an option on the acceptor. 0788 /** 0789 * This function is used to set an option on the acceptor. 0790 * 0791 * @param option The new option value to be set on the acceptor. 0792 * 0793 * @throws boost::system::system_error Thrown on failure. 0794 * 0795 * @sa SettableSocketOption @n 0796 * boost::asio::socket_base::reuse_address 0797 * boost::asio::socket_base::enable_connection_aborted 0798 * 0799 * @par Example 0800 * Setting the SOL_SOCKET/SO_REUSEADDR option: 0801 * @code 0802 * boost::asio::ip::tcp::acceptor acceptor(my_context); 0803 * ... 0804 * boost::asio::ip::tcp::acceptor::reuse_address option(true); 0805 * acceptor.set_option(option); 0806 * @endcode 0807 */ 0808 template <typename SettableSocketOption> 0809 void set_option(const SettableSocketOption& option) 0810 { 0811 boost::system::error_code ec; 0812 impl_.get_service().set_option(impl_.get_implementation(), option, ec); 0813 boost::asio::detail::throw_error(ec, "set_option"); 0814 } 0815 0816 /// Set an option on the acceptor. 0817 /** 0818 * This function is used to set an option on the acceptor. 0819 * 0820 * @param option The new option value to be set on the acceptor. 0821 * 0822 * @param ec Set to indicate what error occurred, if any. 0823 * 0824 * @sa SettableSocketOption @n 0825 * boost::asio::socket_base::reuse_address 0826 * boost::asio::socket_base::enable_connection_aborted 0827 * 0828 * @par Example 0829 * Setting the SOL_SOCKET/SO_REUSEADDR option: 0830 * @code 0831 * boost::asio::ip::tcp::acceptor acceptor(my_context); 0832 * ... 0833 * boost::asio::ip::tcp::acceptor::reuse_address option(true); 0834 * boost::system::error_code ec; 0835 * acceptor.set_option(option, ec); 0836 * if (ec) 0837 * { 0838 * // An error occurred. 0839 * } 0840 * @endcode 0841 */ 0842 template <typename SettableSocketOption> 0843 BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option, 0844 boost::system::error_code& ec) 0845 { 0846 impl_.get_service().set_option(impl_.get_implementation(), option, ec); 0847 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 0848 } 0849 0850 /// Get an option from the acceptor. 0851 /** 0852 * This function is used to get the current value of an option on the 0853 * acceptor. 0854 * 0855 * @param option The option value to be obtained from the acceptor. 0856 * 0857 * @throws boost::system::system_error Thrown on failure. 0858 * 0859 * @sa GettableSocketOption @n 0860 * boost::asio::socket_base::reuse_address 0861 * 0862 * @par Example 0863 * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: 0864 * @code 0865 * boost::asio::ip::tcp::acceptor acceptor(my_context); 0866 * ... 0867 * boost::asio::ip::tcp::acceptor::reuse_address option; 0868 * acceptor.get_option(option); 0869 * bool is_set = option.get(); 0870 * @endcode 0871 */ 0872 template <typename GettableSocketOption> 0873 void get_option(GettableSocketOption& option) const 0874 { 0875 boost::system::error_code ec; 0876 impl_.get_service().get_option(impl_.get_implementation(), option, ec); 0877 boost::asio::detail::throw_error(ec, "get_option"); 0878 } 0879 0880 /// Get an option from the acceptor. 0881 /** 0882 * This function is used to get the current value of an option on the 0883 * acceptor. 0884 * 0885 * @param option The option value to be obtained from the acceptor. 0886 * 0887 * @param ec Set to indicate what error occurred, if any. 0888 * 0889 * @sa GettableSocketOption @n 0890 * boost::asio::socket_base::reuse_address 0891 * 0892 * @par Example 0893 * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: 0894 * @code 0895 * boost::asio::ip::tcp::acceptor acceptor(my_context); 0896 * ... 0897 * boost::asio::ip::tcp::acceptor::reuse_address option; 0898 * boost::system::error_code ec; 0899 * acceptor.get_option(option, ec); 0900 * if (ec) 0901 * { 0902 * // An error occurred. 0903 * } 0904 * bool is_set = option.get(); 0905 * @endcode 0906 */ 0907 template <typename GettableSocketOption> 0908 BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option, 0909 boost::system::error_code& ec) const 0910 { 0911 impl_.get_service().get_option(impl_.get_implementation(), option, ec); 0912 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 0913 } 0914 0915 /// Perform an IO control command on the acceptor. 0916 /** 0917 * This function is used to execute an IO control command on the acceptor. 0918 * 0919 * @param command The IO control command to be performed on the acceptor. 0920 * 0921 * @throws boost::system::system_error Thrown on failure. 0922 * 0923 * @sa IoControlCommand @n 0924 * boost::asio::socket_base::non_blocking_io 0925 * 0926 * @par Example 0927 * Getting the number of bytes ready to read: 0928 * @code 0929 * boost::asio::ip::tcp::acceptor acceptor(my_context); 0930 * ... 0931 * boost::asio::ip::tcp::acceptor::non_blocking_io command(true); 0932 * socket.io_control(command); 0933 * @endcode 0934 */ 0935 template <typename IoControlCommand> 0936 void io_control(IoControlCommand& command) 0937 { 0938 boost::system::error_code ec; 0939 impl_.get_service().io_control(impl_.get_implementation(), command, ec); 0940 boost::asio::detail::throw_error(ec, "io_control"); 0941 } 0942 0943 /// Perform an IO control command on the acceptor. 0944 /** 0945 * This function is used to execute an IO control command on the acceptor. 0946 * 0947 * @param command The IO control command to be performed on the acceptor. 0948 * 0949 * @param ec Set to indicate what error occurred, if any. 0950 * 0951 * @sa IoControlCommand @n 0952 * boost::asio::socket_base::non_blocking_io 0953 * 0954 * @par Example 0955 * Getting the number of bytes ready to read: 0956 * @code 0957 * boost::asio::ip::tcp::acceptor acceptor(my_context); 0958 * ... 0959 * boost::asio::ip::tcp::acceptor::non_blocking_io command(true); 0960 * boost::system::error_code ec; 0961 * socket.io_control(command, ec); 0962 * if (ec) 0963 * { 0964 * // An error occurred. 0965 * } 0966 * @endcode 0967 */ 0968 template <typename IoControlCommand> 0969 BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, 0970 boost::system::error_code& ec) 0971 { 0972 impl_.get_service().io_control(impl_.get_implementation(), command, ec); 0973 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 0974 } 0975 0976 /// Gets the non-blocking mode of the acceptor. 0977 /** 0978 * @returns @c true if the acceptor's synchronous operations will fail with 0979 * boost::asio::error::would_block if they are unable to perform the requested 0980 * operation immediately. If @c false, synchronous operations will block 0981 * until complete. 0982 * 0983 * @note The non-blocking mode has no effect on the behaviour of asynchronous 0984 * operations. Asynchronous operations will never fail with the error 0985 * boost::asio::error::would_block. 0986 */ 0987 bool non_blocking() const 0988 { 0989 return impl_.get_service().non_blocking(impl_.get_implementation()); 0990 } 0991 0992 /// Sets the non-blocking mode of the acceptor. 0993 /** 0994 * @param mode If @c true, the acceptor's synchronous operations will fail 0995 * with boost::asio::error::would_block if they are unable to perform the 0996 * requested operation immediately. If @c false, synchronous operations will 0997 * block until complete. 0998 * 0999 * @throws boost::system::system_error Thrown on failure. 1000 * 1001 * @note The non-blocking mode has no effect on the behaviour of asynchronous 1002 * operations. Asynchronous operations will never fail with the error 1003 * boost::asio::error::would_block. 1004 */ 1005 void non_blocking(bool mode) 1006 { 1007 boost::system::error_code ec; 1008 impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); 1009 boost::asio::detail::throw_error(ec, "non_blocking"); 1010 } 1011 1012 /// Sets the non-blocking mode of the acceptor. 1013 /** 1014 * @param mode If @c true, the acceptor's synchronous operations will fail 1015 * with boost::asio::error::would_block if they are unable to perform the 1016 * requested operation immediately. If @c false, synchronous operations will 1017 * block until complete. 1018 * 1019 * @param ec Set to indicate what error occurred, if any. 1020 * 1021 * @note The non-blocking mode has no effect on the behaviour of asynchronous 1022 * operations. Asynchronous operations will never fail with the error 1023 * boost::asio::error::would_block. 1024 */ 1025 BOOST_ASIO_SYNC_OP_VOID non_blocking( 1026 bool mode, boost::system::error_code& ec) 1027 { 1028 impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); 1029 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 1030 } 1031 1032 /// Gets the non-blocking mode of the native acceptor implementation. 1033 /** 1034 * This function is used to retrieve the non-blocking mode of the underlying 1035 * native acceptor. This mode has no effect on the behaviour of the acceptor 1036 * object's synchronous operations. 1037 * 1038 * @returns @c true if the underlying acceptor is in non-blocking mode and 1039 * direct system calls may fail with boost::asio::error::would_block (or the 1040 * equivalent system error). 1041 * 1042 * @note The current non-blocking mode is cached by the acceptor object. 1043 * Consequently, the return value may be incorrect if the non-blocking mode 1044 * was set directly on the native acceptor. 1045 */ 1046 bool native_non_blocking() const 1047 { 1048 return impl_.get_service().native_non_blocking(impl_.get_implementation()); 1049 } 1050 1051 /// Sets the non-blocking mode of the native acceptor implementation. 1052 /** 1053 * This function is used to modify the non-blocking mode of the underlying 1054 * native acceptor. It has no effect on the behaviour of the acceptor object's 1055 * synchronous operations. 1056 * 1057 * @param mode If @c true, the underlying acceptor is put into non-blocking 1058 * mode and direct system calls may fail with boost::asio::error::would_block 1059 * (or the equivalent system error). 1060 * 1061 * @throws boost::system::system_error Thrown on failure. If the @c mode is 1062 * @c false, but the current value of @c non_blocking() is @c true, this 1063 * function fails with boost::asio::error::invalid_argument, as the 1064 * combination does not make sense. 1065 */ 1066 void native_non_blocking(bool mode) 1067 { 1068 boost::system::error_code ec; 1069 impl_.get_service().native_non_blocking( 1070 impl_.get_implementation(), mode, ec); 1071 boost::asio::detail::throw_error(ec, "native_non_blocking"); 1072 } 1073 1074 /// Sets the non-blocking mode of the native acceptor implementation. 1075 /** 1076 * This function is used to modify the non-blocking mode of the underlying 1077 * native acceptor. It has no effect on the behaviour of the acceptor object's 1078 * synchronous operations. 1079 * 1080 * @param mode If @c true, the underlying acceptor is put into non-blocking 1081 * mode and direct system calls may fail with boost::asio::error::would_block 1082 * (or the equivalent system error). 1083 * 1084 * @param ec Set to indicate what error occurred, if any. If the @c mode is 1085 * @c false, but the current value of @c non_blocking() is @c true, this 1086 * function fails with boost::asio::error::invalid_argument, as the 1087 * combination does not make sense. 1088 */ 1089 BOOST_ASIO_SYNC_OP_VOID native_non_blocking( 1090 bool mode, boost::system::error_code& ec) 1091 { 1092 impl_.get_service().native_non_blocking( 1093 impl_.get_implementation(), mode, ec); 1094 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 1095 } 1096 1097 /// Get the local endpoint of the acceptor. 1098 /** 1099 * This function is used to obtain the locally bound endpoint of the acceptor. 1100 * 1101 * @returns An object that represents the local endpoint of the acceptor. 1102 * 1103 * @throws boost::system::system_error Thrown on failure. 1104 * 1105 * @par Example 1106 * @code 1107 * boost::asio::ip::tcp::acceptor acceptor(my_context); 1108 * ... 1109 * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(); 1110 * @endcode 1111 */ 1112 endpoint_type local_endpoint() const 1113 { 1114 boost::system::error_code ec; 1115 endpoint_type ep = impl_.get_service().local_endpoint( 1116 impl_.get_implementation(), ec); 1117 boost::asio::detail::throw_error(ec, "local_endpoint"); 1118 return ep; 1119 } 1120 1121 /// Get the local endpoint of the acceptor. 1122 /** 1123 * This function is used to obtain the locally bound endpoint of the acceptor. 1124 * 1125 * @param ec Set to indicate what error occurred, if any. 1126 * 1127 * @returns An object that represents the local endpoint of the acceptor. 1128 * Returns a default-constructed endpoint object if an error occurred and the 1129 * error handler did not throw an exception. 1130 * 1131 * @par Example 1132 * @code 1133 * boost::asio::ip::tcp::acceptor acceptor(my_context); 1134 * ... 1135 * boost::system::error_code ec; 1136 * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec); 1137 * if (ec) 1138 * { 1139 * // An error occurred. 1140 * } 1141 * @endcode 1142 */ 1143 endpoint_type local_endpoint(boost::system::error_code& ec) const 1144 { 1145 return impl_.get_service().local_endpoint(impl_.get_implementation(), ec); 1146 } 1147 1148 /// Wait for the acceptor to become ready to read, ready to write, or to have 1149 /// pending error conditions. 1150 /** 1151 * This function is used to perform a blocking wait for an acceptor to enter 1152 * a ready to read, write or error condition state. 1153 * 1154 * @param w Specifies the desired acceptor state. 1155 * 1156 * @par Example 1157 * Waiting for an acceptor to become readable. 1158 * @code 1159 * boost::asio::ip::tcp::acceptor acceptor(my_context); 1160 * ... 1161 * acceptor.wait(boost::asio::ip::tcp::acceptor::wait_read); 1162 * @endcode 1163 */ 1164 void wait(wait_type w) 1165 { 1166 boost::system::error_code ec; 1167 impl_.get_service().wait(impl_.get_implementation(), w, ec); 1168 boost::asio::detail::throw_error(ec, "wait"); 1169 } 1170 1171 /// Wait for the acceptor to become ready to read, ready to write, or to have 1172 /// pending error conditions. 1173 /** 1174 * This function is used to perform a blocking wait for an acceptor to enter 1175 * a ready to read, write or error condition state. 1176 * 1177 * @param w Specifies the desired acceptor state. 1178 * 1179 * @param ec Set to indicate what error occurred, if any. 1180 * 1181 * @par Example 1182 * Waiting for an acceptor to become readable. 1183 * @code 1184 * boost::asio::ip::tcp::acceptor acceptor(my_context); 1185 * ... 1186 * boost::system::error_code ec; 1187 * acceptor.wait(boost::asio::ip::tcp::acceptor::wait_read, ec); 1188 * @endcode 1189 */ 1190 BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec) 1191 { 1192 impl_.get_service().wait(impl_.get_implementation(), w, ec); 1193 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 1194 } 1195 1196 /// Asynchronously wait for the acceptor to become ready to read, ready to 1197 /// write, or to have pending error conditions. 1198 /** 1199 * This function is used to perform an asynchronous wait for an acceptor to 1200 * enter a ready to read, write or error condition state. It is an initiating 1201 * function for an @ref asynchronous_operation, and always returns 1202 * immediately. 1203 * 1204 * @param w Specifies the desired acceptor state. 1205 * 1206 * @param token The @ref completion_token that will be used to produce a 1207 * completion handler, which will be called when the wait completes. 1208 * Potential completion tokens include @ref use_future, @ref use_awaitable, 1209 * @ref yield_context, or a function object with the correct completion 1210 * signature. The function signature of the completion handler must be: 1211 * @code void handler( 1212 * const boost::system::error_code& error // Result of operation. 1213 * ); @endcode 1214 * Regardless of whether the asynchronous operation completes immediately or 1215 * not, the completion handler will not be invoked from within this function. 1216 * On immediate completion, invocation of the handler will be performed in a 1217 * manner equivalent to using boost::asio::post(). 1218 * 1219 * @par Completion Signature 1220 * @code void(boost::system::error_code) @endcode 1221 * 1222 * @par Example 1223 * @code 1224 * void wait_handler(const boost::system::error_code& error) 1225 * { 1226 * if (!error) 1227 * { 1228 * // Wait succeeded. 1229 * } 1230 * } 1231 * 1232 * ... 1233 * 1234 * boost::asio::ip::tcp::acceptor acceptor(my_context); 1235 * ... 1236 * acceptor.async_wait( 1237 * boost::asio::ip::tcp::acceptor::wait_read, 1238 * wait_handler); 1239 * @endcode 1240 * 1241 * @par Per-Operation Cancellation 1242 * On POSIX or Windows operating systems, this asynchronous operation supports 1243 * cancellation for the following boost::asio::cancellation_type values: 1244 * 1245 * @li @c cancellation_type::terminal 1246 * 1247 * @li @c cancellation_type::partial 1248 * 1249 * @li @c cancellation_type::total 1250 */ 1251 template < 1252 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code)) 1253 WaitToken = default_completion_token_t<executor_type>> 1254 auto async_wait(wait_type w, 1255 WaitToken&& token = default_completion_token_t<executor_type>()) 1256 -> decltype( 1257 async_initiate<WaitToken, void (boost::system::error_code)>( 1258 declval<initiate_async_wait>(), token, w)) 1259 { 1260 return async_initiate<WaitToken, void (boost::system::error_code)>( 1261 initiate_async_wait(this), token, w); 1262 } 1263 1264 #if !defined(BOOST_ASIO_NO_EXTENSIONS) 1265 /// Accept a new connection. 1266 /** 1267 * This function is used to accept a new connection from a peer into the 1268 * given socket. The function call will block until a new connection has been 1269 * accepted successfully or an error occurs. 1270 * 1271 * @param peer The socket into which the new connection will be accepted. 1272 * 1273 * @throws boost::system::system_error Thrown on failure. 1274 * 1275 * @par Example 1276 * @code 1277 * boost::asio::ip::tcp::acceptor acceptor(my_context); 1278 * ... 1279 * boost::asio::ip::tcp::socket socket(my_context); 1280 * acceptor.accept(socket); 1281 * @endcode 1282 */ 1283 template <typename Protocol1, typename Executor1> 1284 void accept(basic_socket<Protocol1, Executor1>& peer, 1285 constraint_t< 1286 is_convertible<Protocol, Protocol1>::value 1287 > = 0) 1288 { 1289 boost::system::error_code ec; 1290 impl_.get_service().accept(impl_.get_implementation(), 1291 peer, static_cast<endpoint_type*>(0), ec); 1292 boost::asio::detail::throw_error(ec, "accept"); 1293 } 1294 1295 /// Accept a new connection. 1296 /** 1297 * This function is used to accept a new connection from a peer into the 1298 * given socket. The function call will block until a new connection has been 1299 * accepted successfully or an error occurs. 1300 * 1301 * @param peer The socket into which the new connection will be accepted. 1302 * 1303 * @param ec Set to indicate what error occurred, if any. 1304 * 1305 * @par Example 1306 * @code 1307 * boost::asio::ip::tcp::acceptor acceptor(my_context); 1308 * ... 1309 * boost::asio::ip::tcp::socket socket(my_context); 1310 * boost::system::error_code ec; 1311 * acceptor.accept(socket, ec); 1312 * if (ec) 1313 * { 1314 * // An error occurred. 1315 * } 1316 * @endcode 1317 */ 1318 template <typename Protocol1, typename Executor1> 1319 BOOST_ASIO_SYNC_OP_VOID accept( 1320 basic_socket<Protocol1, Executor1>& peer, boost::system::error_code& ec, 1321 constraint_t< 1322 is_convertible<Protocol, Protocol1>::value 1323 > = 0) 1324 { 1325 impl_.get_service().accept(impl_.get_implementation(), 1326 peer, static_cast<endpoint_type*>(0), ec); 1327 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 1328 } 1329 1330 /// Start an asynchronous accept. 1331 /** 1332 * This function is used to asynchronously accept a new connection into a 1333 * socket, and additionally obtain the endpoint of the remote peer. It is an 1334 * initiating function for an @ref asynchronous_operation, and always returns 1335 * immediately. 1336 * 1337 * @param peer The socket into which the new connection will be accepted. 1338 * Ownership of the peer object is retained by the caller, which must 1339 * guarantee that it is valid until the completion handler is called. 1340 * 1341 * @param token The @ref completion_token that will be used to produce a 1342 * completion handler, which will be called when the accept completes. 1343 * Potential completion tokens include @ref use_future, @ref use_awaitable, 1344 * @ref yield_context, or a function object with the correct completion 1345 * signature. The function signature of the completion handler must be: 1346 * @code void handler( 1347 * const boost::system::error_code& error // Result of operation. 1348 * ); @endcode 1349 * Regardless of whether the asynchronous operation completes immediately or 1350 * not, the completion handler will not be invoked from within this function. 1351 * On immediate completion, invocation of the handler will be performed in a 1352 * manner equivalent to using boost::asio::post(). 1353 * 1354 * @par Completion Signature 1355 * @code void(boost::system::error_code) @endcode 1356 * 1357 * @par Example 1358 * @code 1359 * void accept_handler(const boost::system::error_code& error) 1360 * { 1361 * if (!error) 1362 * { 1363 * // Accept succeeded. 1364 * } 1365 * } 1366 * 1367 * ... 1368 * 1369 * boost::asio::ip::tcp::acceptor acceptor(my_context); 1370 * ... 1371 * boost::asio::ip::tcp::socket socket(my_context); 1372 * acceptor.async_accept(socket, accept_handler); 1373 * @endcode 1374 * 1375 * @par Per-Operation Cancellation 1376 * On POSIX or Windows operating systems, this asynchronous operation supports 1377 * cancellation for the following boost::asio::cancellation_type values: 1378 * 1379 * @li @c cancellation_type::terminal 1380 * 1381 * @li @c cancellation_type::partial 1382 * 1383 * @li @c cancellation_type::total 1384 */ 1385 template <typename Protocol1, typename Executor1, 1386 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code)) 1387 AcceptToken = default_completion_token_t<executor_type>> 1388 auto async_accept(basic_socket<Protocol1, Executor1>& peer, 1389 AcceptToken&& token = default_completion_token_t<executor_type>(), 1390 constraint_t< 1391 is_convertible<Protocol, Protocol1>::value 1392 > = 0) 1393 -> decltype( 1394 async_initiate<AcceptToken, void (boost::system::error_code)>( 1395 declval<initiate_async_accept>(), token, 1396 &peer, static_cast<endpoint_type*>(0))) 1397 { 1398 return async_initiate<AcceptToken, void (boost::system::error_code)>( 1399 initiate_async_accept(this), token, 1400 &peer, static_cast<endpoint_type*>(0)); 1401 } 1402 1403 /// Accept a new connection and obtain the endpoint of the peer 1404 /** 1405 * This function is used to accept a new connection from a peer into the 1406 * given socket, and additionally provide the endpoint of the remote peer. 1407 * The function call will block until a new connection has been accepted 1408 * successfully or an error occurs. 1409 * 1410 * @param peer The socket into which the new connection will be accepted. 1411 * 1412 * @param peer_endpoint An endpoint object which will receive the endpoint of 1413 * the remote peer. 1414 * 1415 * @throws boost::system::system_error Thrown on failure. 1416 * 1417 * @par Example 1418 * @code 1419 * boost::asio::ip::tcp::acceptor acceptor(my_context); 1420 * ... 1421 * boost::asio::ip::tcp::socket socket(my_context); 1422 * boost::asio::ip::tcp::endpoint endpoint; 1423 * acceptor.accept(socket, endpoint); 1424 * @endcode 1425 */ 1426 template <typename Executor1> 1427 void accept(basic_socket<protocol_type, Executor1>& peer, 1428 endpoint_type& peer_endpoint) 1429 { 1430 boost::system::error_code ec; 1431 impl_.get_service().accept(impl_.get_implementation(), 1432 peer, &peer_endpoint, ec); 1433 boost::asio::detail::throw_error(ec, "accept"); 1434 } 1435 1436 /// Accept a new connection and obtain the endpoint of the peer 1437 /** 1438 * This function is used to accept a new connection from a peer into the 1439 * given socket, and additionally provide the endpoint of the remote peer. 1440 * The function call will block until a new connection has been accepted 1441 * successfully or an error occurs. 1442 * 1443 * @param peer The socket into which the new connection will be accepted. 1444 * 1445 * @param peer_endpoint An endpoint object which will receive the endpoint of 1446 * the remote peer. 1447 * 1448 * @param ec Set to indicate what error occurred, if any. 1449 * 1450 * @par Example 1451 * @code 1452 * boost::asio::ip::tcp::acceptor acceptor(my_context); 1453 * ... 1454 * boost::asio::ip::tcp::socket socket(my_context); 1455 * boost::asio::ip::tcp::endpoint endpoint; 1456 * boost::system::error_code ec; 1457 * acceptor.accept(socket, endpoint, ec); 1458 * if (ec) 1459 * { 1460 * // An error occurred. 1461 * } 1462 * @endcode 1463 */ 1464 template <typename Executor1> 1465 BOOST_ASIO_SYNC_OP_VOID accept(basic_socket<protocol_type, Executor1>& peer, 1466 endpoint_type& peer_endpoint, boost::system::error_code& ec) 1467 { 1468 impl_.get_service().accept( 1469 impl_.get_implementation(), peer, &peer_endpoint, ec); 1470 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 1471 } 1472 1473 /// Start an asynchronous accept. 1474 /** 1475 * This function is used to asynchronously accept a new connection into a 1476 * socket, and additionally obtain the endpoint of the remote peer. It is an 1477 * initiating function for an @ref asynchronous_operation, and always returns 1478 * immediately. 1479 * 1480 * @param peer The socket into which the new connection will be accepted. 1481 * Ownership of the peer object is retained by the caller, which must 1482 * guarantee that it is valid until the completion handler is called. 1483 * 1484 * @param peer_endpoint An endpoint object into which the endpoint of the 1485 * remote peer will be written. Ownership of the peer_endpoint object is 1486 * retained by the caller, which must guarantee that it is valid until the 1487 * handler is called. 1488 * 1489 * @param token The @ref completion_token that will be used to produce a 1490 * completion handler, which will be called when the accept completes. 1491 * Potential completion tokens include @ref use_future, @ref use_awaitable, 1492 * @ref yield_context, or a function object with the correct completion 1493 * signature. The function signature of the completion handler must be: 1494 * @code void handler( 1495 * const boost::system::error_code& error // Result of operation. 1496 * ); @endcode 1497 * Regardless of whether the asynchronous operation completes immediately or 1498 * not, the completion handler will not be invoked from within this function. 1499 * On immediate completion, invocation of the handler will be performed in a 1500 * manner equivalent to using boost::asio::post(). 1501 * 1502 * @par Completion Signature 1503 * @code void(boost::system::error_code) @endcode 1504 * 1505 * @par Per-Operation Cancellation 1506 * On POSIX or Windows operating systems, this asynchronous operation supports 1507 * cancellation for the following boost::asio::cancellation_type values: 1508 * 1509 * @li @c cancellation_type::terminal 1510 * 1511 * @li @c cancellation_type::partial 1512 * 1513 * @li @c cancellation_type::total 1514 */ 1515 template <typename Executor1, 1516 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code)) 1517 AcceptToken = default_completion_token_t<executor_type>> 1518 auto async_accept(basic_socket<protocol_type, Executor1>& peer, 1519 endpoint_type& peer_endpoint, 1520 AcceptToken&& token = default_completion_token_t<executor_type>()) 1521 -> decltype( 1522 async_initiate<AcceptToken, void (boost::system::error_code)>( 1523 declval<initiate_async_accept>(), token, &peer, &peer_endpoint)) 1524 { 1525 return async_initiate<AcceptToken, void (boost::system::error_code)>( 1526 initiate_async_accept(this), token, &peer, &peer_endpoint); 1527 } 1528 #endif // !defined(BOOST_ASIO_NO_EXTENSIONS) 1529 1530 /// Accept a new connection. 1531 /** 1532 * This function is used to accept a new connection from a peer. The function 1533 * call will block until a new connection has been accepted successfully or 1534 * an error occurs. 1535 * 1536 * This overload requires that the Protocol template parameter satisfy the 1537 * AcceptableProtocol type requirements. 1538 * 1539 * @returns A socket object representing the newly accepted connection. 1540 * 1541 * @throws boost::system::system_error Thrown on failure. 1542 * 1543 * @par Example 1544 * @code 1545 * boost::asio::ip::tcp::acceptor acceptor(my_context); 1546 * ... 1547 * boost::asio::ip::tcp::socket socket(acceptor.accept()); 1548 * @endcode 1549 */ 1550 typename Protocol::socket::template rebind_executor<executor_type>::other 1551 accept() 1552 { 1553 boost::system::error_code ec; 1554 typename Protocol::socket::template rebind_executor< 1555 executor_type>::other peer(impl_.get_executor()); 1556 impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); 1557 boost::asio::detail::throw_error(ec, "accept"); 1558 return peer; 1559 } 1560 1561 /// Accept a new connection. 1562 /** 1563 * This function is used to accept a new connection from a peer. The function 1564 * call will block until a new connection has been accepted successfully or 1565 * an error occurs. 1566 * 1567 * This overload requires that the Protocol template parameter satisfy the 1568 * AcceptableProtocol type requirements. 1569 * 1570 * @param ec Set to indicate what error occurred, if any. 1571 * 1572 * @returns On success, a socket object representing the newly accepted 1573 * connection. On error, a socket object where is_open() is false. 1574 * 1575 * @par Example 1576 * @code 1577 * boost::asio::ip::tcp::acceptor acceptor(my_context); 1578 * ... 1579 * boost::asio::ip::tcp::socket socket(acceptor.accept(ec)); 1580 * if (ec) 1581 * { 1582 * // An error occurred. 1583 * } 1584 * @endcode 1585 */ 1586 typename Protocol::socket::template rebind_executor<executor_type>::other 1587 accept(boost::system::error_code& ec) 1588 { 1589 typename Protocol::socket::template rebind_executor< 1590 executor_type>::other peer(impl_.get_executor()); 1591 impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); 1592 return peer; 1593 } 1594 1595 /// Start an asynchronous accept. 1596 /** 1597 * This function is used to asynchronously accept a new connection. It is an 1598 * initiating function for an @ref asynchronous_operation, and always returns 1599 * immediately. 1600 * 1601 * This overload requires that the Protocol template parameter satisfy the 1602 * AcceptableProtocol type requirements. 1603 * 1604 * @param token The @ref completion_token that will be used to produce a 1605 * completion handler, which will be called when the accept completes. 1606 * Potential completion tokens include @ref use_future, @ref use_awaitable, 1607 * @ref yield_context, or a function object with the correct completion 1608 * signature. The function signature of the completion handler must be: 1609 * @code void handler( 1610 * // Result of operation. 1611 * const boost::system::error_code& error, 1612 * 1613 * // On success, the newly accepted socket. 1614 * typename Protocol::socket::template 1615 * rebind_executor<executor_type>::other peer 1616 * ); @endcode 1617 * Regardless of whether the asynchronous operation completes immediately or 1618 * not, the completion handler will not be invoked from within this function. 1619 * On immediate completion, invocation of the handler will be performed in a 1620 * manner equivalent to using boost::asio::post(). 1621 * 1622 * @par Completion Signature 1623 * @code void(boost::system::error_code, 1624 * typename Protocol::socket::template 1625 * rebind_executor<executor_type>::other)) @endcode 1626 * 1627 * @par Example 1628 * @code 1629 * void accept_handler(const boost::system::error_code& error, 1630 * boost::asio::ip::tcp::socket peer) 1631 * { 1632 * if (!error) 1633 * { 1634 * // Accept succeeded. 1635 * } 1636 * } 1637 * 1638 * ... 1639 * 1640 * boost::asio::ip::tcp::acceptor acceptor(my_context); 1641 * ... 1642 * acceptor.async_accept(accept_handler); 1643 * @endcode 1644 * 1645 * @par Per-Operation Cancellation 1646 * On POSIX or Windows operating systems, this asynchronous operation supports 1647 * cancellation for the following boost::asio::cancellation_type values: 1648 * 1649 * @li @c cancellation_type::terminal 1650 * 1651 * @li @c cancellation_type::partial 1652 * 1653 * @li @c cancellation_type::total 1654 */ 1655 template < 1656 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, 1657 typename Protocol::socket::template rebind_executor< 1658 executor_type>::other)) MoveAcceptToken 1659 = default_completion_token_t<executor_type>> 1660 auto async_accept( 1661 MoveAcceptToken&& token = default_completion_token_t<executor_type>()) 1662 -> decltype( 1663 async_initiate<MoveAcceptToken, 1664 void (boost::system::error_code, typename Protocol::socket::template 1665 rebind_executor<executor_type>::other)>( 1666 declval<initiate_async_move_accept>(), token, 1667 declval<const executor_type&>(), static_cast<endpoint_type*>(0), 1668 static_cast<typename Protocol::socket::template 1669 rebind_executor<executor_type>::other*>(0))) 1670 { 1671 return async_initiate<MoveAcceptToken, 1672 void (boost::system::error_code, typename Protocol::socket::template 1673 rebind_executor<executor_type>::other)>( 1674 initiate_async_move_accept(this), token, 1675 impl_.get_executor(), static_cast<endpoint_type*>(0), 1676 static_cast<typename Protocol::socket::template 1677 rebind_executor<executor_type>::other*>(0)); 1678 } 1679 1680 /// Accept a new connection. 1681 /** 1682 * This function is used to accept a new connection from a peer. The function 1683 * call will block until a new connection has been accepted successfully or 1684 * an error occurs. 1685 * 1686 * This overload requires that the Protocol template parameter satisfy the 1687 * AcceptableProtocol type requirements. 1688 * 1689 * @param ex The I/O executor object to be used for the newly 1690 * accepted socket. 1691 * 1692 * @returns A socket object representing the newly accepted connection. 1693 * 1694 * @throws boost::system::system_error Thrown on failure. 1695 * 1696 * @par Example 1697 * @code 1698 * boost::asio::ip::tcp::acceptor acceptor(my_context); 1699 * ... 1700 * boost::asio::ip::tcp::socket socket(acceptor.accept()); 1701 * @endcode 1702 */ 1703 template <typename Executor1> 1704 typename Protocol::socket::template rebind_executor<Executor1>::other 1705 accept(const Executor1& ex, 1706 constraint_t< 1707 is_executor<Executor1>::value 1708 || execution::is_executor<Executor1>::value 1709 > = 0) 1710 { 1711 boost::system::error_code ec; 1712 typename Protocol::socket::template 1713 rebind_executor<Executor1>::other peer(ex); 1714 impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); 1715 boost::asio::detail::throw_error(ec, "accept"); 1716 return peer; 1717 } 1718 1719 /// Accept a new connection. 1720 /** 1721 * This function is used to accept a new connection from a peer. The function 1722 * call will block until a new connection has been accepted successfully or 1723 * an error occurs. 1724 * 1725 * This overload requires that the Protocol template parameter satisfy the 1726 * AcceptableProtocol type requirements. 1727 * 1728 * @param context The I/O execution context object to be used for the newly 1729 * accepted socket. 1730 * 1731 * @returns A socket object representing the newly accepted connection. 1732 * 1733 * @throws boost::system::system_error Thrown on failure. 1734 * 1735 * @par Example 1736 * @code 1737 * boost::asio::ip::tcp::acceptor acceptor(my_context); 1738 * ... 1739 * boost::asio::ip::tcp::socket socket(acceptor.accept()); 1740 * @endcode 1741 */ 1742 template <typename ExecutionContext> 1743 typename Protocol::socket::template rebind_executor< 1744 typename ExecutionContext::executor_type>::other 1745 accept(ExecutionContext& context, 1746 constraint_t< 1747 is_convertible<ExecutionContext&, execution_context&>::value 1748 > = 0) 1749 { 1750 boost::system::error_code ec; 1751 typename Protocol::socket::template rebind_executor< 1752 typename ExecutionContext::executor_type>::other peer(context); 1753 impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); 1754 boost::asio::detail::throw_error(ec, "accept"); 1755 return peer; 1756 } 1757 1758 /// Accept a new connection. 1759 /** 1760 * This function is used to accept a new connection from a peer. The function 1761 * call will block until a new connection has been accepted successfully or 1762 * an error occurs. 1763 * 1764 * This overload requires that the Protocol template parameter satisfy the 1765 * AcceptableProtocol type requirements. 1766 * 1767 * @param ex The I/O executor object to be used for the newly accepted 1768 * socket. 1769 * 1770 * @param ec Set to indicate what error occurred, if any. 1771 * 1772 * @returns On success, a socket object representing the newly accepted 1773 * connection. On error, a socket object where is_open() is false. 1774 * 1775 * @par Example 1776 * @code 1777 * boost::asio::ip::tcp::acceptor acceptor(my_context); 1778 * ... 1779 * boost::asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec)); 1780 * if (ec) 1781 * { 1782 * // An error occurred. 1783 * } 1784 * @endcode 1785 */ 1786 template <typename Executor1> 1787 typename Protocol::socket::template rebind_executor<Executor1>::other 1788 accept(const Executor1& ex, boost::system::error_code& ec, 1789 constraint_t< 1790 is_executor<Executor1>::value 1791 || execution::is_executor<Executor1>::value 1792 > = 0) 1793 { 1794 typename Protocol::socket::template 1795 rebind_executor<Executor1>::other peer(ex); 1796 impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); 1797 return peer; 1798 } 1799 1800 /// Accept a new connection. 1801 /** 1802 * This function is used to accept a new connection from a peer. The function 1803 * call will block until a new connection has been accepted successfully or 1804 * an error occurs. 1805 * 1806 * This overload requires that the Protocol template parameter satisfy the 1807 * AcceptableProtocol type requirements. 1808 * 1809 * @param context The I/O execution context object to be used for the newly 1810 * accepted socket. 1811 * 1812 * @param ec Set to indicate what error occurred, if any. 1813 * 1814 * @returns On success, a socket object representing the newly accepted 1815 * connection. On error, a socket object where is_open() is false. 1816 * 1817 * @par Example 1818 * @code 1819 * boost::asio::ip::tcp::acceptor acceptor(my_context); 1820 * ... 1821 * boost::asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec)); 1822 * if (ec) 1823 * { 1824 * // An error occurred. 1825 * } 1826 * @endcode 1827 */ 1828 template <typename ExecutionContext> 1829 typename Protocol::socket::template rebind_executor< 1830 typename ExecutionContext::executor_type>::other 1831 accept(ExecutionContext& context, boost::system::error_code& ec, 1832 constraint_t< 1833 is_convertible<ExecutionContext&, execution_context&>::value 1834 > = 0) 1835 { 1836 typename Protocol::socket::template rebind_executor< 1837 typename ExecutionContext::executor_type>::other peer(context); 1838 impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); 1839 return peer; 1840 } 1841 1842 /// Start an asynchronous accept. 1843 /** 1844 * This function is used to asynchronously accept a new connection. It is an 1845 * initiating function for an @ref asynchronous_operation, and always returns 1846 * immediately. 1847 * 1848 * This overload requires that the Protocol template parameter satisfy the 1849 * AcceptableProtocol type requirements. 1850 * 1851 * @param ex The I/O executor object to be used for the newly accepted 1852 * socket. 1853 * 1854 * @param token The @ref completion_token that will be used to produce a 1855 * completion handler, which will be called when the accept completes. 1856 * Potential completion tokens include @ref use_future, @ref use_awaitable, 1857 * @ref yield_context, or a function object with the correct completion 1858 * signature. The function signature of the completion handler must be: 1859 * @code void handler( 1860 * // Result of operation. 1861 * const boost::system::error_code& error, 1862 * 1863 * // On success, the newly accepted socket. 1864 * typename Protocol::socket::template rebind_executor< 1865 * Executor1>::other peer 1866 * ); @endcode 1867 * Regardless of whether the asynchronous operation completes immediately or 1868 * not, the completion handler will not be invoked from within this function. 1869 * On immediate completion, invocation of the handler will be performed in a 1870 * manner equivalent to using boost::asio::post(). 1871 * 1872 * @par Completion Signature 1873 * @code void(boost::system::error_code, 1874 * typename Protocol::socket::template rebind_executor< 1875 * Executor1>::other)) @endcode 1876 * 1877 * @par Example 1878 * @code 1879 * void accept_handler(const boost::system::error_code& error, 1880 * boost::asio::ip::tcp::socket peer) 1881 * { 1882 * if (!error) 1883 * { 1884 * // Accept succeeded. 1885 * } 1886 * } 1887 * 1888 * ... 1889 * 1890 * boost::asio::ip::tcp::acceptor acceptor(my_context); 1891 * ... 1892 * acceptor.async_accept(my_context2, accept_handler); 1893 * @endcode 1894 * 1895 * @par Per-Operation Cancellation 1896 * On POSIX or Windows operating systems, this asynchronous operation supports 1897 * cancellation for the following boost::asio::cancellation_type values: 1898 * 1899 * @li @c cancellation_type::terminal 1900 * 1901 * @li @c cancellation_type::partial 1902 * 1903 * @li @c cancellation_type::total 1904 */ 1905 template <typename Executor1, 1906 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, 1907 typename Protocol::socket::template rebind_executor< 1908 constraint_t<is_executor<Executor1>::value 1909 || execution::is_executor<Executor1>::value, 1910 Executor1>>::other)) MoveAcceptToken 1911 = default_completion_token_t<executor_type>> 1912 auto async_accept(const Executor1& ex, 1913 MoveAcceptToken&& token = default_completion_token_t<executor_type>(), 1914 constraint_t< 1915 is_executor<Executor1>::value 1916 || execution::is_executor<Executor1>::value 1917 > = 0) 1918 -> decltype( 1919 async_initiate<MoveAcceptToken, 1920 void (boost::system::error_code, 1921 typename Protocol::socket::template rebind_executor< 1922 Executor1>::other)>( 1923 declval<initiate_async_move_accept>(), token, 1924 ex, static_cast<endpoint_type*>(0), 1925 static_cast<typename Protocol::socket::template 1926 rebind_executor<Executor1>::other*>(0))) 1927 { 1928 return async_initiate<MoveAcceptToken, 1929 void (boost::system::error_code, 1930 typename Protocol::socket::template rebind_executor< 1931 Executor1>::other)>( 1932 initiate_async_move_accept(this), token, 1933 ex, static_cast<endpoint_type*>(0), 1934 static_cast<typename Protocol::socket::template 1935 rebind_executor<Executor1>::other*>(0)); 1936 } 1937 1938 /// Start an asynchronous accept. 1939 /** 1940 * This function is used to asynchronously accept a new connection. It is an 1941 * initiating function for an @ref asynchronous_operation, and always returns 1942 * immediately. 1943 * 1944 * This overload requires that the Protocol template parameter satisfy the 1945 * AcceptableProtocol type requirements. 1946 * 1947 * @param context The I/O execution context object to be used for the newly 1948 * accepted socket. 1949 * 1950 * @param token The @ref completion_token that will be used to produce a 1951 * completion handler, which will be called when the accept completes. 1952 * Potential completion tokens include @ref use_future, @ref use_awaitable, 1953 * @ref yield_context, or a function object with the correct completion 1954 * signature. The function signature of the completion handler must be: 1955 * @code void handler( 1956 * // Result of operation. 1957 * const boost::system::error_code& error, 1958 * 1959 * // On success, the newly accepted socket. 1960 * typename Protocol::socket::template rebind_executor< 1961 * typename ExecutionContext::executor_type>::other peer 1962 * ); @endcode 1963 * Regardless of whether the asynchronous operation completes immediately or 1964 * not, the completion handler will not be invoked from within this function. 1965 * On immediate completion, invocation of the handler will be performed in a 1966 * manner equivalent to using boost::asio::post(). 1967 * 1968 * @par Completion Signature 1969 * @code void(boost::system::error_code, 1970 * typename Protocol::socket::template rebind_executor< 1971 * typename ExecutionContext::executor_type>::other)) @endcode 1972 * 1973 * @par Example 1974 * @code 1975 * void accept_handler(const boost::system::error_code& error, 1976 * boost::asio::ip::tcp::socket peer) 1977 * { 1978 * if (!error) 1979 * { 1980 * // Accept succeeded. 1981 * } 1982 * } 1983 * 1984 * ... 1985 * 1986 * boost::asio::ip::tcp::acceptor acceptor(my_context); 1987 * ... 1988 * acceptor.async_accept(my_context2, accept_handler); 1989 * @endcode 1990 * 1991 * @par Per-Operation Cancellation 1992 * On POSIX or Windows operating systems, this asynchronous operation supports 1993 * cancellation for the following boost::asio::cancellation_type values: 1994 * 1995 * @li @c cancellation_type::terminal 1996 * 1997 * @li @c cancellation_type::partial 1998 * 1999 * @li @c cancellation_type::total 2000 */ 2001 template <typename ExecutionContext, 2002 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, 2003 typename Protocol::socket::template rebind_executor< 2004 typename ExecutionContext::executor_type>::other)) MoveAcceptToken 2005 = default_completion_token_t<executor_type>> 2006 auto async_accept(ExecutionContext& context, 2007 MoveAcceptToken&& token = default_completion_token_t<executor_type>(), 2008 constraint_t< 2009 is_convertible<ExecutionContext&, execution_context&>::value 2010 > = 0) 2011 -> decltype( 2012 async_initiate<MoveAcceptToken, 2013 void (boost::system::error_code, 2014 typename Protocol::socket::template rebind_executor< 2015 typename ExecutionContext::executor_type>::other)>( 2016 declval<initiate_async_move_accept>(), token, 2017 context.get_executor(), static_cast<endpoint_type*>(0), 2018 static_cast<typename Protocol::socket::template rebind_executor< 2019 typename ExecutionContext::executor_type>::other*>(0))) 2020 { 2021 return async_initiate<MoveAcceptToken, 2022 void (boost::system::error_code, 2023 typename Protocol::socket::template rebind_executor< 2024 typename ExecutionContext::executor_type>::other)>( 2025 initiate_async_move_accept(this), token, 2026 context.get_executor(), static_cast<endpoint_type*>(0), 2027 static_cast<typename Protocol::socket::template rebind_executor< 2028 typename ExecutionContext::executor_type>::other*>(0)); 2029 } 2030 2031 /// Accept a new connection. 2032 /** 2033 * This function is used to accept a new connection from a peer. The function 2034 * call will block until a new connection has been accepted successfully or 2035 * an error occurs. 2036 * 2037 * This overload requires that the Protocol template parameter satisfy the 2038 * AcceptableProtocol type requirements. 2039 * 2040 * @param peer_endpoint An endpoint object into which the endpoint of the 2041 * remote peer will be written. 2042 * 2043 * @returns A socket object representing the newly accepted connection. 2044 * 2045 * @throws boost::system::system_error Thrown on failure. 2046 * 2047 * @par Example 2048 * @code 2049 * boost::asio::ip::tcp::acceptor acceptor(my_context); 2050 * ... 2051 * boost::asio::ip::tcp::endpoint endpoint; 2052 * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint)); 2053 * @endcode 2054 */ 2055 typename Protocol::socket::template rebind_executor<executor_type>::other 2056 accept(endpoint_type& peer_endpoint) 2057 { 2058 boost::system::error_code ec; 2059 typename Protocol::socket::template rebind_executor< 2060 executor_type>::other peer(impl_.get_executor()); 2061 impl_.get_service().accept(impl_.get_implementation(), 2062 peer, &peer_endpoint, ec); 2063 boost::asio::detail::throw_error(ec, "accept"); 2064 return peer; 2065 } 2066 2067 /// Accept a new connection. 2068 /** 2069 * This function is used to accept a new connection from a peer. The function 2070 * call will block until a new connection has been accepted successfully or 2071 * an error occurs. 2072 * 2073 * This overload requires that the Protocol template parameter satisfy the 2074 * AcceptableProtocol type requirements. 2075 * 2076 * @param peer_endpoint An endpoint object into which the endpoint of the 2077 * remote peer will be written. 2078 * 2079 * @param ec Set to indicate what error occurred, if any. 2080 * 2081 * @returns On success, a socket object representing the newly accepted 2082 * connection. On error, a socket object where is_open() is false. 2083 * 2084 * @par Example 2085 * @code 2086 * boost::asio::ip::tcp::acceptor acceptor(my_context); 2087 * ... 2088 * boost::asio::ip::tcp::endpoint endpoint; 2089 * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint, ec)); 2090 * if (ec) 2091 * { 2092 * // An error occurred. 2093 * } 2094 * @endcode 2095 */ 2096 typename Protocol::socket::template rebind_executor<executor_type>::other 2097 accept(endpoint_type& peer_endpoint, boost::system::error_code& ec) 2098 { 2099 typename Protocol::socket::template rebind_executor< 2100 executor_type>::other peer(impl_.get_executor()); 2101 impl_.get_service().accept(impl_.get_implementation(), 2102 peer, &peer_endpoint, ec); 2103 return peer; 2104 } 2105 2106 /// Start an asynchronous accept. 2107 /** 2108 * This function is used to asynchronously accept a new connection. It is an 2109 * initiating function for an @ref asynchronous_operation, and always returns 2110 * immediately. 2111 * 2112 * This overload requires that the Protocol template parameter satisfy the 2113 * AcceptableProtocol type requirements. 2114 * 2115 * @param peer_endpoint An endpoint object into which the endpoint of the 2116 * remote peer will be written. Ownership of the peer_endpoint object is 2117 * retained by the caller, which must guarantee that it is valid until the 2118 * completion handler is called. 2119 * 2120 * @param token The @ref completion_token that will be used to produce a 2121 * completion handler, which will be called when the accept completes. 2122 * Potential completion tokens include @ref use_future, @ref use_awaitable, 2123 * @ref yield_context, or a function object with the correct completion 2124 * signature. The function signature of the completion handler must be: 2125 * @code void handler( 2126 * // Result of operation. 2127 * const boost::system::error_code& error, 2128 * 2129 * // On success, the newly accepted socket. 2130 * typename Protocol::socket::template 2131 * rebind_executor<executor_type>::other peer 2132 * ); @endcode 2133 * Regardless of whether the asynchronous operation completes immediately or 2134 * not, the completion handler will not be invoked from within this function. 2135 * On immediate completion, invocation of the handler will be performed in a 2136 * manner equivalent to using boost::asio::post(). 2137 * 2138 * @par Completion Signature 2139 * @code void(boost::system::error_code, 2140 * typename Protocol::socket::template 2141 * rebind_executor<executor_type>::other)) @endcode 2142 * 2143 * @par Example 2144 * @code 2145 * void accept_handler(const boost::system::error_code& error, 2146 * boost::asio::ip::tcp::socket peer) 2147 * { 2148 * if (!error) 2149 * { 2150 * // Accept succeeded. 2151 * } 2152 * } 2153 * 2154 * ... 2155 * 2156 * boost::asio::ip::tcp::acceptor acceptor(my_context); 2157 * ... 2158 * boost::asio::ip::tcp::endpoint endpoint; 2159 * acceptor.async_accept(endpoint, accept_handler); 2160 * @endcode 2161 * 2162 * @par Per-Operation Cancellation 2163 * On POSIX or Windows operating systems, this asynchronous operation supports 2164 * cancellation for the following boost::asio::cancellation_type values: 2165 * 2166 * @li @c cancellation_type::terminal 2167 * 2168 * @li @c cancellation_type::partial 2169 * 2170 * @li @c cancellation_type::total 2171 */ 2172 template < 2173 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, 2174 typename Protocol::socket::template rebind_executor< 2175 executor_type>::other)) MoveAcceptToken 2176 = default_completion_token_t<executor_type>> 2177 auto async_accept(endpoint_type& peer_endpoint, 2178 MoveAcceptToken&& token = default_completion_token_t<executor_type>()) 2179 -> decltype( 2180 async_initiate<MoveAcceptToken, 2181 void (boost::system::error_code, typename Protocol::socket::template 2182 rebind_executor<executor_type>::other)>( 2183 declval<initiate_async_move_accept>(), token, 2184 declval<const executor_type&>(), &peer_endpoint, 2185 static_cast<typename Protocol::socket::template 2186 rebind_executor<executor_type>::other*>(0))) 2187 { 2188 return async_initiate<MoveAcceptToken, 2189 void (boost::system::error_code, typename Protocol::socket::template 2190 rebind_executor<executor_type>::other)>( 2191 initiate_async_move_accept(this), token, 2192 impl_.get_executor(), &peer_endpoint, 2193 static_cast<typename Protocol::socket::template 2194 rebind_executor<executor_type>::other*>(0)); 2195 } 2196 2197 /// Accept a new connection. 2198 /** 2199 * This function is used to accept a new connection from a peer. The function 2200 * call will block until a new connection has been accepted successfully or 2201 * an error occurs. 2202 * 2203 * This overload requires that the Protocol template parameter satisfy the 2204 * AcceptableProtocol type requirements. 2205 * 2206 * @param ex The I/O executor object to be used for the newly accepted 2207 * socket. 2208 * 2209 * @param peer_endpoint An endpoint object into which the endpoint of the 2210 * remote peer will be written. 2211 * 2212 * @returns A socket object representing the newly accepted connection. 2213 * 2214 * @throws boost::system::system_error Thrown on failure. 2215 * 2216 * @par Example 2217 * @code 2218 * boost::asio::ip::tcp::acceptor acceptor(my_context); 2219 * ... 2220 * boost::asio::ip::tcp::endpoint endpoint; 2221 * boost::asio::ip::tcp::socket socket( 2222 * acceptor.accept(my_context2, endpoint)); 2223 * @endcode 2224 */ 2225 template <typename Executor1> 2226 typename Protocol::socket::template rebind_executor<Executor1>::other 2227 accept(const Executor1& ex, endpoint_type& peer_endpoint, 2228 constraint_t< 2229 is_executor<Executor1>::value 2230 || execution::is_executor<Executor1>::value 2231 > = 0) 2232 { 2233 boost::system::error_code ec; 2234 typename Protocol::socket::template 2235 rebind_executor<Executor1>::other peer(ex); 2236 impl_.get_service().accept(impl_.get_implementation(), 2237 peer, &peer_endpoint, ec); 2238 boost::asio::detail::throw_error(ec, "accept"); 2239 return peer; 2240 } 2241 2242 /// Accept a new connection. 2243 /** 2244 * This function is used to accept a new connection from a peer. The function 2245 * call will block until a new connection has been accepted successfully or 2246 * an error occurs. 2247 * 2248 * This overload requires that the Protocol template parameter satisfy the 2249 * AcceptableProtocol type requirements. 2250 * 2251 * @param context The I/O execution context object to be used for the newly 2252 * accepted socket. 2253 * 2254 * @param peer_endpoint An endpoint object into which the endpoint of the 2255 * remote peer will be written. 2256 * 2257 * @returns A socket object representing the newly accepted connection. 2258 * 2259 * @throws boost::system::system_error Thrown on failure. 2260 * 2261 * @par Example 2262 * @code 2263 * boost::asio::ip::tcp::acceptor acceptor(my_context); 2264 * ... 2265 * boost::asio::ip::tcp::endpoint endpoint; 2266 * boost::asio::ip::tcp::socket socket( 2267 * acceptor.accept(my_context2, endpoint)); 2268 * @endcode 2269 */ 2270 template <typename ExecutionContext> 2271 typename Protocol::socket::template rebind_executor< 2272 typename ExecutionContext::executor_type>::other 2273 accept(ExecutionContext& context, endpoint_type& peer_endpoint, 2274 constraint_t< 2275 is_convertible<ExecutionContext&, execution_context&>::value 2276 > = 0) 2277 { 2278 boost::system::error_code ec; 2279 typename Protocol::socket::template rebind_executor< 2280 typename ExecutionContext::executor_type>::other peer(context); 2281 impl_.get_service().accept(impl_.get_implementation(), 2282 peer, &peer_endpoint, ec); 2283 boost::asio::detail::throw_error(ec, "accept"); 2284 return peer; 2285 } 2286 2287 /// Accept a new connection. 2288 /** 2289 * This function is used to accept a new connection from a peer. The function 2290 * call will block until a new connection has been accepted successfully or 2291 * an error occurs. 2292 * 2293 * This overload requires that the Protocol template parameter satisfy the 2294 * AcceptableProtocol type requirements. 2295 * 2296 * @param ex The I/O executor object to be used for the newly accepted 2297 * socket. 2298 * 2299 * @param peer_endpoint An endpoint object into which the endpoint of the 2300 * remote peer will be written. 2301 * 2302 * @param ec Set to indicate what error occurred, if any. 2303 * 2304 * @returns On success, a socket object representing the newly accepted 2305 * connection. On error, a socket object where is_open() is false. 2306 * 2307 * @par Example 2308 * @code 2309 * boost::asio::ip::tcp::acceptor acceptor(my_context); 2310 * ... 2311 * boost::asio::ip::tcp::endpoint endpoint; 2312 * boost::asio::ip::tcp::socket socket( 2313 * acceptor.accept(my_context2, endpoint, ec)); 2314 * if (ec) 2315 * { 2316 * // An error occurred. 2317 * } 2318 * @endcode 2319 */ 2320 template <typename Executor1> 2321 typename Protocol::socket::template rebind_executor<Executor1>::other 2322 accept(const executor_type& ex, 2323 endpoint_type& peer_endpoint, boost::system::error_code& ec, 2324 constraint_t< 2325 is_executor<Executor1>::value 2326 || execution::is_executor<Executor1>::value 2327 > = 0) 2328 { 2329 typename Protocol::socket::template 2330 rebind_executor<Executor1>::other peer(ex); 2331 impl_.get_service().accept(impl_.get_implementation(), 2332 peer, &peer_endpoint, ec); 2333 return peer; 2334 } 2335 2336 /// Accept a new connection. 2337 /** 2338 * This function is used to accept a new connection from a peer. The function 2339 * call will block until a new connection has been accepted successfully or 2340 * an error occurs. 2341 * 2342 * This overload requires that the Protocol template parameter satisfy the 2343 * AcceptableProtocol type requirements. 2344 * 2345 * @param context The I/O execution context object to be used for the newly 2346 * accepted socket. 2347 * 2348 * @param peer_endpoint An endpoint object into which the endpoint of the 2349 * remote peer will be written. 2350 * 2351 * @param ec Set to indicate what error occurred, if any. 2352 * 2353 * @returns On success, a socket object representing the newly accepted 2354 * connection. On error, a socket object where is_open() is false. 2355 * 2356 * @par Example 2357 * @code 2358 * boost::asio::ip::tcp::acceptor acceptor(my_context); 2359 * ... 2360 * boost::asio::ip::tcp::endpoint endpoint; 2361 * boost::asio::ip::tcp::socket socket( 2362 * acceptor.accept(my_context2, endpoint, ec)); 2363 * if (ec) 2364 * { 2365 * // An error occurred. 2366 * } 2367 * @endcode 2368 */ 2369 template <typename ExecutionContext> 2370 typename Protocol::socket::template rebind_executor< 2371 typename ExecutionContext::executor_type>::other 2372 accept(ExecutionContext& context, 2373 endpoint_type& peer_endpoint, boost::system::error_code& ec, 2374 constraint_t< 2375 is_convertible<ExecutionContext&, execution_context&>::value 2376 > = 0) 2377 { 2378 typename Protocol::socket::template rebind_executor< 2379 typename ExecutionContext::executor_type>::other peer(context); 2380 impl_.get_service().accept(impl_.get_implementation(), 2381 peer, &peer_endpoint, ec); 2382 return peer; 2383 } 2384 2385 /// Start an asynchronous accept. 2386 /** 2387 * This function is used to asynchronously accept a new connection. It is an 2388 * initiating function for an @ref asynchronous_operation, and always returns 2389 * immediately. 2390 * 2391 * This overload requires that the Protocol template parameter satisfy the 2392 * AcceptableProtocol type requirements. 2393 * 2394 * @param ex The I/O executor object to be used for the newly accepted 2395 * socket. 2396 * 2397 * @param peer_endpoint An endpoint object into which the endpoint of the 2398 * remote peer will be written. Ownership of the peer_endpoint object is 2399 * retained by the caller, which must guarantee that it is valid until the 2400 * completion handler is called. 2401 * 2402 * @param token The @ref completion_token that will be used to produce a 2403 * completion handler, which will be called when the accept completes. 2404 * Potential completion tokens include @ref use_future, @ref use_awaitable, 2405 * @ref yield_context, or a function object with the correct completion 2406 * signature. The function signature of the completion handler must be: 2407 * @code void handler( 2408 * // Result of operation. 2409 * const boost::system::error_code& error, 2410 * 2411 * // On success, the newly accepted socket. 2412 * typename Protocol::socket::template rebind_executor< 2413 * Executor1>::other peer 2414 * ); @endcode 2415 * Regardless of whether the asynchronous operation completes immediately or 2416 * not, the completion handler will not be invoked from within this function. 2417 * On immediate completion, invocation of the handler will be performed in a 2418 * manner equivalent to using boost::asio::post(). 2419 * 2420 * @par Completion Signature 2421 * @code void(boost::system::error_code, 2422 * typename Protocol::socket::template rebind_executor< 2423 * Executor1>::other)) @endcode 2424 * 2425 * @par Example 2426 * @code 2427 * void accept_handler(const boost::system::error_code& error, 2428 * boost::asio::ip::tcp::socket peer) 2429 * { 2430 * if (!error) 2431 * { 2432 * // Accept succeeded. 2433 * } 2434 * } 2435 * 2436 * ... 2437 * 2438 * boost::asio::ip::tcp::acceptor acceptor(my_context); 2439 * ... 2440 * boost::asio::ip::tcp::endpoint endpoint; 2441 * acceptor.async_accept(my_context2, endpoint, accept_handler); 2442 * @endcode 2443 * 2444 * @par Per-Operation Cancellation 2445 * On POSIX or Windows operating systems, this asynchronous operation supports 2446 * cancellation for the following boost::asio::cancellation_type values: 2447 * 2448 * @li @c cancellation_type::terminal 2449 * 2450 * @li @c cancellation_type::partial 2451 * 2452 * @li @c cancellation_type::total 2453 */ 2454 template <typename Executor1, 2455 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, 2456 typename Protocol::socket::template rebind_executor< 2457 constraint_t<is_executor<Executor1>::value 2458 || execution::is_executor<Executor1>::value, 2459 Executor1>>::other)) MoveAcceptToken 2460 = default_completion_token_t<executor_type>> 2461 auto async_accept(const Executor1& ex, endpoint_type& peer_endpoint, 2462 MoveAcceptToken&& token = default_completion_token_t<executor_type>(), 2463 constraint_t< 2464 is_executor<Executor1>::value 2465 || execution::is_executor<Executor1>::value 2466 > = 0) 2467 -> decltype( 2468 async_initiate<MoveAcceptToken, 2469 void (boost::system::error_code, 2470 typename Protocol::socket::template rebind_executor< 2471 Executor1>::other)>( 2472 declval<initiate_async_move_accept>(), token, ex, &peer_endpoint, 2473 static_cast<typename Protocol::socket::template 2474 rebind_executor<Executor1>::other*>(0))) 2475 { 2476 return async_initiate<MoveAcceptToken, 2477 void (boost::system::error_code, 2478 typename Protocol::socket::template rebind_executor< 2479 Executor1>::other)>( 2480 initiate_async_move_accept(this), token, ex, &peer_endpoint, 2481 static_cast<typename Protocol::socket::template 2482 rebind_executor<Executor1>::other*>(0)); 2483 } 2484 2485 /// Start an asynchronous accept. 2486 /** 2487 * This function is used to asynchronously accept a new connection. It is an 2488 * initiating function for an @ref asynchronous_operation, and always returns 2489 * immediately. 2490 * 2491 * This overload requires that the Protocol template parameter satisfy the 2492 * AcceptableProtocol type requirements. 2493 * 2494 * @param context The I/O execution context object to be used for the newly 2495 * accepted socket. 2496 * 2497 * @param peer_endpoint An endpoint object into which the endpoint of the 2498 * remote peer will be written. Ownership of the peer_endpoint object is 2499 * retained by the caller, which must guarantee that it is valid until the 2500 * completion handler is called. 2501 * 2502 * @param token The @ref completion_token that will be used to produce a 2503 * completion handler, which will be called when the accept completes. 2504 * Potential completion tokens include @ref use_future, @ref use_awaitable, 2505 * @ref yield_context, or a function object with the correct completion 2506 * signature. The function signature of the completion handler must be: 2507 * @code void handler( 2508 * // Result of operation. 2509 * const boost::system::error_code& error, 2510 * 2511 * // On success, the newly accepted socket. 2512 * typename Protocol::socket::template rebind_executor< 2513 * typename ExecutionContext::executor_type>::other peer 2514 * ); @endcode 2515 * Regardless of whether the asynchronous operation completes immediately or 2516 * not, the completion handler will not be invoked from within this function. 2517 * On immediate completion, invocation of the handler will be performed in a 2518 * manner equivalent to using boost::asio::post(). 2519 * 2520 * @par Completion Signature 2521 * @code void(boost::system::error_code, 2522 * typename Protocol::socket::template rebind_executor< 2523 * typename ExecutionContext::executor_type>::other)) @endcode 2524 * 2525 * @par Example 2526 * @code 2527 * void accept_handler(const boost::system::error_code& error, 2528 * boost::asio::ip::tcp::socket peer) 2529 * { 2530 * if (!error) 2531 * { 2532 * // Accept succeeded. 2533 * } 2534 * } 2535 * 2536 * ... 2537 * 2538 * boost::asio::ip::tcp::acceptor acceptor(my_context); 2539 * ... 2540 * boost::asio::ip::tcp::endpoint endpoint; 2541 * acceptor.async_accept(my_context2, endpoint, accept_handler); 2542 * @endcode 2543 * 2544 * @par Per-Operation Cancellation 2545 * On POSIX or Windows operating systems, this asynchronous operation supports 2546 * cancellation for the following boost::asio::cancellation_type values: 2547 * 2548 * @li @c cancellation_type::terminal 2549 * 2550 * @li @c cancellation_type::partial 2551 * 2552 * @li @c cancellation_type::total 2553 */ 2554 template <typename ExecutionContext, 2555 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, 2556 typename Protocol::socket::template rebind_executor< 2557 typename ExecutionContext::executor_type>::other)) MoveAcceptToken 2558 = default_completion_token_t<executor_type>> 2559 auto async_accept(ExecutionContext& context, endpoint_type& peer_endpoint, 2560 MoveAcceptToken&& token = default_completion_token_t<executor_type>(), 2561 constraint_t< 2562 is_convertible<ExecutionContext&, execution_context&>::value 2563 > = 0) 2564 -> decltype( 2565 async_initiate<MoveAcceptToken, 2566 void (boost::system::error_code, 2567 typename Protocol::socket::template rebind_executor< 2568 typename ExecutionContext::executor_type>::other)>( 2569 declval<initiate_async_move_accept>(), token, 2570 context.get_executor(), &peer_endpoint, 2571 static_cast<typename Protocol::socket::template rebind_executor< 2572 typename ExecutionContext::executor_type>::other*>(0))) 2573 { 2574 return async_initiate<MoveAcceptToken, 2575 void (boost::system::error_code, 2576 typename Protocol::socket::template rebind_executor< 2577 typename ExecutionContext::executor_type>::other)>( 2578 initiate_async_move_accept(this), token, 2579 context.get_executor(), &peer_endpoint, 2580 static_cast<typename Protocol::socket::template rebind_executor< 2581 typename ExecutionContext::executor_type>::other*>(0)); 2582 } 2583 2584 private: 2585 // Disallow copying and assignment. 2586 basic_socket_acceptor(const basic_socket_acceptor&) = delete; 2587 basic_socket_acceptor& operator=( 2588 const basic_socket_acceptor&) = delete; 2589 2590 class initiate_async_wait 2591 { 2592 public: 2593 typedef Executor executor_type; 2594 2595 explicit initiate_async_wait(basic_socket_acceptor* self) 2596 : self_(self) 2597 { 2598 } 2599 2600 const executor_type& get_executor() const noexcept 2601 { 2602 return self_->get_executor(); 2603 } 2604 2605 template <typename WaitHandler> 2606 void operator()(WaitHandler&& handler, wait_type w) const 2607 { 2608 // If you get an error on the following line it means that your handler 2609 // does not meet the documented type requirements for a WaitHandler. 2610 BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; 2611 2612 detail::non_const_lvalue<WaitHandler> handler2(handler); 2613 self_->impl_.get_service().async_wait( 2614 self_->impl_.get_implementation(), w, 2615 handler2.value, self_->impl_.get_executor()); 2616 } 2617 2618 private: 2619 basic_socket_acceptor* self_; 2620 }; 2621 2622 class initiate_async_accept 2623 { 2624 public: 2625 typedef Executor executor_type; 2626 2627 explicit initiate_async_accept(basic_socket_acceptor* self) 2628 : self_(self) 2629 { 2630 } 2631 2632 const executor_type& get_executor() const noexcept 2633 { 2634 return self_->get_executor(); 2635 } 2636 2637 template <typename AcceptHandler, typename Protocol1, typename Executor1> 2638 void operator()(AcceptHandler&& handler, 2639 basic_socket<Protocol1, Executor1>* peer, 2640 endpoint_type* peer_endpoint) const 2641 { 2642 // If you get an error on the following line it means that your handler 2643 // does not meet the documented type requirements for a AcceptHandler. 2644 BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check; 2645 2646 detail::non_const_lvalue<AcceptHandler> handler2(handler); 2647 self_->impl_.get_service().async_accept( 2648 self_->impl_.get_implementation(), *peer, peer_endpoint, 2649 handler2.value, self_->impl_.get_executor()); 2650 } 2651 2652 private: 2653 basic_socket_acceptor* self_; 2654 }; 2655 2656 class initiate_async_move_accept 2657 { 2658 public: 2659 typedef Executor executor_type; 2660 2661 explicit initiate_async_move_accept(basic_socket_acceptor* self) 2662 : self_(self) 2663 { 2664 } 2665 2666 const executor_type& get_executor() const noexcept 2667 { 2668 return self_->get_executor(); 2669 } 2670 2671 template <typename MoveAcceptHandler, typename Executor1, typename Socket> 2672 void operator()(MoveAcceptHandler&& handler, 2673 const Executor1& peer_ex, endpoint_type* peer_endpoint, Socket*) const 2674 { 2675 // If you get an error on the following line it means that your handler 2676 // does not meet the documented type requirements for a MoveAcceptHandler. 2677 BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( 2678 MoveAcceptHandler, handler, Socket) type_check; 2679 2680 detail::non_const_lvalue<MoveAcceptHandler> handler2(handler); 2681 self_->impl_.get_service().async_move_accept( 2682 self_->impl_.get_implementation(), peer_ex, peer_endpoint, 2683 handler2.value, self_->impl_.get_executor()); 2684 } 2685 2686 private: 2687 basic_socket_acceptor* self_; 2688 }; 2689 2690 #if defined(BOOST_ASIO_WINDOWS_RUNTIME) 2691 detail::io_object_impl< 2692 detail::null_socket_service<Protocol>, Executor> impl_; 2693 #elif defined(BOOST_ASIO_HAS_IOCP) 2694 detail::io_object_impl< 2695 detail::win_iocp_socket_service<Protocol>, Executor> impl_; 2696 #elif defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT) 2697 detail::io_object_impl< 2698 detail::io_uring_socket_service<Protocol>, Executor> impl_; 2699 #else 2700 detail::io_object_impl< 2701 detail::reactive_socket_service<Protocol>, Executor> impl_; 2702 #endif 2703 }; 2704 2705 } // namespace asio 2706 } // namespace boost 2707 2708 #include <boost/asio/detail/pop_options.hpp> 2709 2710 #endif // BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_HPP
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |