1 // 2 // basic_socket_acceptor.hpp 3 // ~~~~~~~~~~~~~~~~~~~~~~~~~ 4 // 5 // Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com) 6 // 7 // Distributed under the Boost Software License, Version 1.0. (See accompanying 8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 9 // 10 11 #ifndef BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_HPP 12 #define BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_HPP 13 14 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 15 # pragma once 16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 17 18 #include <boost/asio/detail/config.hpp> 19 #include <boost/asio/any_io_executor.hpp> 20 #include <boost/asio/basic_socket.hpp> 21 #include <boost/asio/detail/handler_type_requirements.hpp> 22 #include <boost/asio/detail/io_object_impl.hpp> 23 #include <boost/asio/detail/non_const_lvalue.hpp> 24 #include <boost/asio/detail/throw_error.hpp> 25 #include <boost/asio/detail/type_traits.hpp> 26 #include <boost/asio/error.hpp> 27 #include <boost/asio/execution_context.hpp> 28 #include <boost/asio/socket_base.hpp> 29 30 #if defined(BOOST_ASIO_WINDOWS_RUNTIME) 31 # include <boost/asio/detail/null_socket_service.hpp> 32 #elif defined(BOOST_ASIO_HAS_IOCP) 33 # include <boost/asio/detail/win_iocp_socket_service.hpp> 34 #elif defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT) 35 # include <boost/asio/detail/io_uring_socket_service.hpp> 36 #else 37 # include <boost/asio/detail/reactive_socket_service.hpp> 38 #endif 39 40 #if defined(BOOST_ASIO_HAS_MOVE) 41 # include <utility> 42 #endif // defined(BOOST_ASIO_HAS_MOVE) 43 44 #include <boost/asio/detail/push_options.hpp> 45 46 namespace boost { 47 namespace asio { 48 49 #if !defined(BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL) 50 #define BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL 51 52 // Forward declaration with defaulted arguments. 53 template <typename Protocol, typename Executor = any_io_executor> 54 class basic_socket_acceptor; 55 56 #endif // !defined(BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL) 57 58 /// Provides the ability to accept new connections. 59 /** 60 * The basic_socket_acceptor class template is used for accepting new socket 61 * connections. 62 * 63 * @par Thread Safety 64 * @e Distinct @e objects: Safe.@n 65 * @e Shared @e objects: Unsafe. 66 * 67 * Synchronous @c accept operations are thread safe, if the underlying 68 * operating system calls are also thread safe. This means that it is permitted 69 * to perform concurrent calls to synchronous @c accept operations on a single 70 * socket object. Other synchronous operations, such as @c open or @c close, are 71 * not thread safe. 72 * 73 * @par Example 74 * Opening a socket acceptor with the SO_REUSEADDR option enabled: 75 * @code 76 * boost::asio::ip::tcp::acceptor acceptor(my_context); 77 * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), port); 78 * acceptor.open(endpoint.protocol()); 79 * acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); 80 * acceptor.bind(endpoint); 81 * acceptor.listen(); 82 * @endcode 83 */ 84 template <typename Protocol, typename Executor> 85 class basic_socket_acceptor 86 : public socket_base 87 { 88 public: 89 /// The type of the executor associated with the object. 90 typedef Executor executor_type; 91 92 /// Rebinds the acceptor type to another executor. 93 template <typename Executor1> 94 struct rebind_executor 95 { 96 /// The socket type when rebound to the specified executor. 97 typedef basic_socket_acceptor<Protocol, Executor1> other; 98 }; 99 100 /// The native representation of an acceptor. 101 #if defined(GENERATING_DOCUMENTATION) 102 typedef implementation_defined native_handle_type; 103 #elif defined(BOOST_ASIO_WINDOWS_RUNTIME) 104 typedef typename detail::null_socket_service< 105 Protocol>::native_handle_type native_handle_type; 106 #elif defined(BOOST_ASIO_HAS_IOCP) 107 typedef typename detail::win_iocp_socket_service< 108 Protocol>::native_handle_type native_handle_type; 109 #elif defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT) 110 typedef typename detail::io_uring_socket_service< 111 Protocol>::native_handle_type native_handle_type; 112 #else 113 typedef typename detail::reactive_socket_service< 114 Protocol>::native_handle_type native_handle_type; 115 #endif 116 117 /// The protocol type. 118 typedef Protocol protocol_type; 119 120 /// The endpoint type. 121 typedef typename Protocol::endpoint endpoint_type; 122 123 /// Construct an acceptor without opening it. 124 /** 125 * This constructor creates an acceptor without opening it to listen for new 126 * connections. The open() function must be called before the acceptor can 127 * accept new socket connections. 128 * 129 * @param ex The I/O executor that the acceptor will use, by default, to 130 * dispatch handlers for any asynchronous operations performed on the 131 * acceptor. 132 */ basic_socket_acceptor(const executor_type & ex)133 explicit basic_socket_acceptor(const executor_type& ex) 134 : impl_(0, ex) 135 { 136 } 137 138 /// Construct an acceptor without opening it. 139 /** 140 * This constructor creates an acceptor without opening it to listen for new 141 * connections. The open() function must be called before the acceptor can 142 * accept new socket connections. 143 * 144 * @param context An execution context which provides the I/O executor that 145 * the acceptor will use, by default, to dispatch handlers for any 146 * asynchronous operations performed on the acceptor. 147 */ 148 template <typename ExecutionContext> basic_socket_acceptor(ExecutionContext & context,typename constraint<is_convertible<ExecutionContext &,execution_context &>::value>::type=0)149 explicit basic_socket_acceptor(ExecutionContext& context, 150 typename constraint< 151 is_convertible<ExecutionContext&, execution_context&>::value 152 >::type = 0) 153 : impl_(0, 0, context) 154 { 155 } 156 157 /// Construct an open acceptor. 158 /** 159 * This constructor creates an acceptor and automatically opens it. 160 * 161 * @param ex The I/O executor that the acceptor will use, by default, to 162 * dispatch handlers for any asynchronous operations performed on the 163 * acceptor. 164 * 165 * @param protocol An object specifying protocol parameters to be used. 166 * 167 * @throws boost::system::system_error Thrown on failure. 168 */ basic_socket_acceptor(const executor_type & ex,const protocol_type & protocol)169 basic_socket_acceptor(const executor_type& ex, const protocol_type& protocol) 170 : impl_(0, ex) 171 { 172 boost::system::error_code ec; 173 impl_.get_service().open(impl_.get_implementation(), protocol, ec); 174 boost::asio::detail::throw_error(ec, "open"); 175 } 176 177 /// Construct an open acceptor. 178 /** 179 * This constructor creates an acceptor and automatically opens it. 180 * 181 * @param context An execution context which provides the I/O executor that 182 * the acceptor will use, by default, to dispatch handlers for any 183 * asynchronous operations performed on the acceptor. 184 * 185 * @param protocol An object specifying protocol parameters to be used. 186 * 187 * @throws boost::system::system_error Thrown on failure. 188 */ 189 template <typename ExecutionContext> basic_socket_acceptor(ExecutionContext & context,const protocol_type & protocol,typename constraint<is_convertible<ExecutionContext &,execution_context &>::value,defaulted_constraint>::type=defaulted_constraint ())190 basic_socket_acceptor(ExecutionContext& context, 191 const protocol_type& protocol, 192 typename constraint< 193 is_convertible<ExecutionContext&, execution_context&>::value, 194 defaulted_constraint 195 >::type = defaulted_constraint()) 196 : impl_(0, 0, context) 197 { 198 boost::system::error_code ec; 199 impl_.get_service().open(impl_.get_implementation(), protocol, ec); 200 boost::asio::detail::throw_error(ec, "open"); 201 } 202 203 /// Construct an acceptor opened on the given endpoint. 204 /** 205 * This constructor creates an acceptor and automatically opens it to listen 206 * for new connections on the specified endpoint. 207 * 208 * @param ex The I/O executor that the acceptor will use, by default, to 209 * dispatch handlers for any asynchronous operations performed on the 210 * acceptor. 211 * 212 * @param endpoint An endpoint on the local machine on which the acceptor 213 * will listen for new connections. 214 * 215 * @param reuse_addr Whether the constructor should set the socket option 216 * socket_base::reuse_address. 217 * 218 * @throws boost::system::system_error Thrown on failure. 219 * 220 * @note This constructor is equivalent to the following code: 221 * @code 222 * basic_socket_acceptor<Protocol> acceptor(my_context); 223 * acceptor.open(endpoint.protocol()); 224 * if (reuse_addr) 225 * acceptor.set_option(socket_base::reuse_address(true)); 226 * acceptor.bind(endpoint); 227 * acceptor.listen(); 228 * @endcode 229 */ basic_socket_acceptor(const executor_type & ex,const endpoint_type & endpoint,bool reuse_addr=true)230 basic_socket_acceptor(const executor_type& ex, 231 const endpoint_type& endpoint, bool reuse_addr = true) 232 : impl_(0, ex) 233 { 234 boost::system::error_code ec; 235 const protocol_type protocol = endpoint.protocol(); 236 impl_.get_service().open(impl_.get_implementation(), protocol, ec); 237 boost::asio::detail::throw_error(ec, "open"); 238 if (reuse_addr) 239 { 240 impl_.get_service().set_option(impl_.get_implementation(), 241 socket_base::reuse_address(true), ec); 242 boost::asio::detail::throw_error(ec, "set_option"); 243 } 244 impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); 245 boost::asio::detail::throw_error(ec, "bind"); 246 impl_.get_service().listen(impl_.get_implementation(), 247 socket_base::max_listen_connections, ec); 248 boost::asio::detail::throw_error(ec, "listen"); 249 } 250 251 /// Construct an acceptor opened on the given endpoint. 252 /** 253 * This constructor creates an acceptor and automatically opens it to listen 254 * for new connections on the specified endpoint. 255 * 256 * @param context An execution context which provides the I/O executor that 257 * the acceptor will use, by default, to dispatch handlers for any 258 * asynchronous operations performed on the acceptor. 259 * 260 * @param endpoint An endpoint on the local machine on which the acceptor 261 * will listen for new connections. 262 * 263 * @param reuse_addr Whether the constructor should set the socket option 264 * socket_base::reuse_address. 265 * 266 * @throws boost::system::system_error Thrown on failure. 267 * 268 * @note This constructor is equivalent to the following code: 269 * @code 270 * basic_socket_acceptor<Protocol> acceptor(my_context); 271 * acceptor.open(endpoint.protocol()); 272 * if (reuse_addr) 273 * acceptor.set_option(socket_base::reuse_address(true)); 274 * acceptor.bind(endpoint); 275 * acceptor.listen(); 276 * @endcode 277 */ 278 template <typename ExecutionContext> basic_socket_acceptor(ExecutionContext & context,const endpoint_type & endpoint,bool reuse_addr=true,typename constraint<is_convertible<ExecutionContext &,execution_context &>::value>::type=0)279 basic_socket_acceptor(ExecutionContext& context, 280 const endpoint_type& endpoint, bool reuse_addr = true, 281 typename constraint< 282 is_convertible<ExecutionContext&, execution_context&>::value 283 >::type = 0) 284 : impl_(0, 0, context) 285 { 286 boost::system::error_code ec; 287 const protocol_type protocol = endpoint.protocol(); 288 impl_.get_service().open(impl_.get_implementation(), protocol, ec); 289 boost::asio::detail::throw_error(ec, "open"); 290 if (reuse_addr) 291 { 292 impl_.get_service().set_option(impl_.get_implementation(), 293 socket_base::reuse_address(true), ec); 294 boost::asio::detail::throw_error(ec, "set_option"); 295 } 296 impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); 297 boost::asio::detail::throw_error(ec, "bind"); 298 impl_.get_service().listen(impl_.get_implementation(), 299 socket_base::max_listen_connections, ec); 300 boost::asio::detail::throw_error(ec, "listen"); 301 } 302 303 /// Construct a basic_socket_acceptor on an existing native acceptor. 304 /** 305 * This constructor creates an acceptor object to hold an existing native 306 * acceptor. 307 * 308 * @param ex The I/O executor that the acceptor will use, by default, to 309 * dispatch handlers for any asynchronous operations performed on the 310 * acceptor. 311 * 312 * @param protocol An object specifying protocol parameters to be used. 313 * 314 * @param native_acceptor A native acceptor. 315 * 316 * @throws boost::system::system_error Thrown on failure. 317 */ basic_socket_acceptor(const executor_type & ex,const protocol_type & protocol,const native_handle_type & native_acceptor)318 basic_socket_acceptor(const executor_type& ex, 319 const protocol_type& protocol, const native_handle_type& native_acceptor) 320 : impl_(0, ex) 321 { 322 boost::system::error_code ec; 323 impl_.get_service().assign(impl_.get_implementation(), 324 protocol, native_acceptor, ec); 325 boost::asio::detail::throw_error(ec, "assign"); 326 } 327 328 /// Construct a basic_socket_acceptor on an existing native acceptor. 329 /** 330 * This constructor creates an acceptor object to hold an existing native 331 * acceptor. 332 * 333 * @param context An execution context which provides the I/O executor that 334 * the acceptor will use, by default, to dispatch handlers for any 335 * asynchronous operations performed on the acceptor. 336 * 337 * @param protocol An object specifying protocol parameters to be used. 338 * 339 * @param native_acceptor A native acceptor. 340 * 341 * @throws boost::system::system_error Thrown on failure. 342 */ 343 template <typename ExecutionContext> basic_socket_acceptor(ExecutionContext & context,const protocol_type & protocol,const native_handle_type & native_acceptor,typename constraint<is_convertible<ExecutionContext &,execution_context &>::value>::type=0)344 basic_socket_acceptor(ExecutionContext& context, 345 const protocol_type& protocol, const native_handle_type& native_acceptor, 346 typename constraint< 347 is_convertible<ExecutionContext&, execution_context&>::value 348 >::type = 0) 349 : impl_(0, 0, context) 350 { 351 boost::system::error_code ec; 352 impl_.get_service().assign(impl_.get_implementation(), 353 protocol, native_acceptor, ec); 354 boost::asio::detail::throw_error(ec, "assign"); 355 } 356 357 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) 358 /// Move-construct a basic_socket_acceptor from another. 359 /** 360 * This constructor moves an acceptor from one object to another. 361 * 362 * @param other The other basic_socket_acceptor object from which the move 363 * will occur. 364 * 365 * @note Following the move, the moved-from object is in the same state as if 366 * constructed using the @c basic_socket_acceptor(const executor_type&) 367 * constructor. 368 */ basic_socket_acceptor(basic_socket_acceptor && other)369 basic_socket_acceptor(basic_socket_acceptor&& other) BOOST_ASIO_NOEXCEPT 370 : impl_(std::move(other.impl_)) 371 { 372 } 373 374 /// Move-assign a basic_socket_acceptor from another. 375 /** 376 * This assignment operator moves an acceptor from one object to another. 377 * 378 * @param other The other basic_socket_acceptor object from which the move 379 * will occur. 380 * 381 * @note Following the move, the moved-from object is in the same state as if 382 * constructed using the @c basic_socket_acceptor(const executor_type&) 383 * constructor. 384 */ operator =(basic_socket_acceptor && other)385 basic_socket_acceptor& operator=(basic_socket_acceptor&& other) 386 { 387 impl_ = std::move(other.impl_); 388 return *this; 389 } 390 391 // All socket acceptors have access to each other's implementations. 392 template <typename Protocol1, typename Executor1> 393 friend class basic_socket_acceptor; 394 395 /// Move-construct a basic_socket_acceptor from an acceptor of another 396 /// protocol type. 397 /** 398 * This constructor moves an acceptor from one object to another. 399 * 400 * @param other The other basic_socket_acceptor object from which the move 401 * will occur. 402 * 403 * @note Following the move, the moved-from object is in the same state as if 404 * constructed using the @c basic_socket_acceptor(const executor_type&) 405 * constructor. 406 */ 407 template <typename Protocol1, typename Executor1> basic_socket_acceptor(basic_socket_acceptor<Protocol1,Executor1> && other,typename constraint<is_convertible<Protocol1,Protocol>::value && is_convertible<Executor1,Executor>::value>::type=0)408 basic_socket_acceptor(basic_socket_acceptor<Protocol1, Executor1>&& other, 409 typename constraint< 410 is_convertible<Protocol1, Protocol>::value 411 && is_convertible<Executor1, Executor>::value 412 >::type = 0) 413 : impl_(std::move(other.impl_)) 414 { 415 } 416 417 /// Move-assign a basic_socket_acceptor from an acceptor of another protocol 418 /// type. 419 /** 420 * This assignment operator moves an acceptor from one object to another. 421 * 422 * @param other The other basic_socket_acceptor object from which the move 423 * will occur. 424 * 425 * @note Following the move, the moved-from object is in the same state as if 426 * constructed using the @c basic_socket_acceptor(const executor_type&) 427 * constructor. 428 */ 429 template <typename Protocol1, typename Executor1> 430 typename constraint< 431 is_convertible<Protocol1, Protocol>::value 432 && is_convertible<Executor1, Executor>::value, 433 basic_socket_acceptor& operator =(basic_socket_acceptor<Protocol1,Executor1> && other)434 >::type operator=(basic_socket_acceptor<Protocol1, Executor1>&& other) 435 { 436 basic_socket_acceptor tmp(std::move(other)); 437 impl_ = std::move(tmp.impl_); 438 return *this; 439 } 440 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) 441 442 /// Destroys the acceptor. 443 /** 444 * This function destroys the acceptor, cancelling any outstanding 445 * asynchronous operations associated with the acceptor as if by calling 446 * @c cancel. 447 */ ~basic_socket_acceptor()448 ~basic_socket_acceptor() 449 { 450 } 451 452 /// Get the executor associated with the object. get_executor()453 executor_type get_executor() BOOST_ASIO_NOEXCEPT 454 { 455 return impl_.get_executor(); 456 } 457 458 /// Open the acceptor using the specified protocol. 459 /** 460 * This function opens the socket acceptor so that it will use the specified 461 * protocol. 462 * 463 * @param protocol An object specifying which protocol is to be used. 464 * 465 * @throws boost::system::system_error Thrown on failure. 466 * 467 * @par Example 468 * @code 469 * boost::asio::ip::tcp::acceptor acceptor(my_context); 470 * acceptor.open(boost::asio::ip::tcp::v4()); 471 * @endcode 472 */ open(const protocol_type & protocol=protocol_type ())473 void open(const protocol_type& protocol = protocol_type()) 474 { 475 boost::system::error_code ec; 476 impl_.get_service().open(impl_.get_implementation(), protocol, ec); 477 boost::asio::detail::throw_error(ec, "open"); 478 } 479 480 /// Open the acceptor using the specified protocol. 481 /** 482 * This function opens the socket acceptor so that it will use the specified 483 * protocol. 484 * 485 * @param protocol An object specifying which protocol is to be used. 486 * 487 * @param ec Set to indicate what error occurred, if any. 488 * 489 * @par Example 490 * @code 491 * boost::asio::ip::tcp::acceptor acceptor(my_context); 492 * boost::system::error_code ec; 493 * acceptor.open(boost::asio::ip::tcp::v4(), ec); 494 * if (ec) 495 * { 496 * // An error occurred. 497 * } 498 * @endcode 499 */ open(const protocol_type & protocol,boost::system::error_code & ec)500 BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol, 501 boost::system::error_code& ec) 502 { 503 impl_.get_service().open(impl_.get_implementation(), protocol, ec); 504 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 505 } 506 507 /// Assigns an existing native acceptor to the acceptor. 508 /* 509 * This function opens the acceptor to hold an existing native acceptor. 510 * 511 * @param protocol An object specifying which protocol is to be used. 512 * 513 * @param native_acceptor A native acceptor. 514 * 515 * @throws boost::system::system_error Thrown on failure. 516 */ assign(const protocol_type & protocol,const native_handle_type & native_acceptor)517 void assign(const protocol_type& protocol, 518 const native_handle_type& native_acceptor) 519 { 520 boost::system::error_code ec; 521 impl_.get_service().assign(impl_.get_implementation(), 522 protocol, native_acceptor, ec); 523 boost::asio::detail::throw_error(ec, "assign"); 524 } 525 526 /// Assigns an existing native acceptor to the acceptor. 527 /* 528 * This function opens the acceptor to hold an existing native acceptor. 529 * 530 * @param protocol An object specifying which protocol is to be used. 531 * 532 * @param native_acceptor A native acceptor. 533 * 534 * @param ec Set to indicate what error occurred, if any. 535 */ assign(const protocol_type & protocol,const native_handle_type & native_acceptor,boost::system::error_code & ec)536 BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol, 537 const native_handle_type& native_acceptor, boost::system::error_code& ec) 538 { 539 impl_.get_service().assign(impl_.get_implementation(), 540 protocol, native_acceptor, ec); 541 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 542 } 543 544 /// Determine whether the acceptor is open. is_open() const545 bool is_open() const 546 { 547 return impl_.get_service().is_open(impl_.get_implementation()); 548 } 549 550 /// Bind the acceptor to the given local endpoint. 551 /** 552 * This function binds the socket acceptor to the specified endpoint on the 553 * local machine. 554 * 555 * @param endpoint An endpoint on the local machine to which the socket 556 * acceptor will be bound. 557 * 558 * @throws boost::system::system_error Thrown on failure. 559 * 560 * @par Example 561 * @code 562 * boost::asio::ip::tcp::acceptor acceptor(my_context); 563 * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345); 564 * acceptor.open(endpoint.protocol()); 565 * acceptor.bind(endpoint); 566 * @endcode 567 */ bind(const endpoint_type & endpoint)568 void bind(const endpoint_type& endpoint) 569 { 570 boost::system::error_code ec; 571 impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); 572 boost::asio::detail::throw_error(ec, "bind"); 573 } 574 575 /// Bind the acceptor to the given local endpoint. 576 /** 577 * This function binds the socket acceptor to the specified endpoint on the 578 * local machine. 579 * 580 * @param endpoint An endpoint on the local machine to which the socket 581 * acceptor will be bound. 582 * 583 * @param ec Set to indicate what error occurred, if any. 584 * 585 * @par Example 586 * @code 587 * boost::asio::ip::tcp::acceptor acceptor(my_context); 588 * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345); 589 * acceptor.open(endpoint.protocol()); 590 * boost::system::error_code ec; 591 * acceptor.bind(endpoint, ec); 592 * if (ec) 593 * { 594 * // An error occurred. 595 * } 596 * @endcode 597 */ bind(const endpoint_type & endpoint,boost::system::error_code & ec)598 BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint, 599 boost::system::error_code& ec) 600 { 601 impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); 602 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 603 } 604 605 /// Place the acceptor into the state where it will listen for new 606 /// connections. 607 /** 608 * This function puts the socket acceptor into the state where it may accept 609 * new connections. 610 * 611 * @param backlog The maximum length of the queue of pending connections. 612 * 613 * @throws boost::system::system_error Thrown on failure. 614 */ listen(int backlog=socket_base::max_listen_connections)615 void listen(int backlog = socket_base::max_listen_connections) 616 { 617 boost::system::error_code ec; 618 impl_.get_service().listen(impl_.get_implementation(), backlog, ec); 619 boost::asio::detail::throw_error(ec, "listen"); 620 } 621 622 /// Place the acceptor into the state where it will listen for new 623 /// connections. 624 /** 625 * This function puts the socket acceptor into the state where it may accept 626 * new connections. 627 * 628 * @param backlog The maximum length of the queue of pending connections. 629 * 630 * @param ec Set to indicate what error occurred, if any. 631 * 632 * @par Example 633 * @code 634 * boost::asio::ip::tcp::acceptor acceptor(my_context); 635 * ... 636 * boost::system::error_code ec; 637 * acceptor.listen(boost::asio::socket_base::max_listen_connections, ec); 638 * if (ec) 639 * { 640 * // An error occurred. 641 * } 642 * @endcode 643 */ listen(int backlog,boost::system::error_code & ec)644 BOOST_ASIO_SYNC_OP_VOID listen(int backlog, boost::system::error_code& ec) 645 { 646 impl_.get_service().listen(impl_.get_implementation(), backlog, ec); 647 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 648 } 649 650 /// Close the acceptor. 651 /** 652 * This function is used to close the acceptor. Any asynchronous accept 653 * operations will be cancelled immediately. 654 * 655 * A subsequent call to open() is required before the acceptor can again be 656 * used to again perform socket accept operations. 657 * 658 * @throws boost::system::system_error Thrown on failure. 659 */ close()660 void close() 661 { 662 boost::system::error_code ec; 663 impl_.get_service().close(impl_.get_implementation(), ec); 664 boost::asio::detail::throw_error(ec, "close"); 665 } 666 667 /// Close the acceptor. 668 /** 669 * This function is used to close the acceptor. Any asynchronous accept 670 * operations will be cancelled immediately. 671 * 672 * A subsequent call to open() is required before the acceptor can again be 673 * used to again perform socket accept operations. 674 * 675 * @param ec Set to indicate what error occurred, if any. 676 * 677 * @par Example 678 * @code 679 * boost::asio::ip::tcp::acceptor acceptor(my_context); 680 * ... 681 * boost::system::error_code ec; 682 * acceptor.close(ec); 683 * if (ec) 684 * { 685 * // An error occurred. 686 * } 687 * @endcode 688 */ close(boost::system::error_code & ec)689 BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec) 690 { 691 impl_.get_service().close(impl_.get_implementation(), ec); 692 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 693 } 694 695 /// Release ownership of the underlying native acceptor. 696 /** 697 * This function causes all outstanding asynchronous accept operations to 698 * finish immediately, and the handlers for cancelled operations will be 699 * passed the boost::asio::error::operation_aborted error. Ownership of the 700 * native acceptor is then transferred to the caller. 701 * 702 * @throws boost::system::system_error Thrown on failure. 703 * 704 * @note This function is unsupported on Windows versions prior to Windows 705 * 8.1, and will fail with boost::asio::error::operation_not_supported on 706 * these platforms. 707 */ 708 #if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ 709 && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) 710 __declspec(deprecated("This function always fails with " 711 "operation_not_supported when used on Windows versions " 712 "prior to Windows 8.1.")) 713 #endif release()714 native_handle_type release() 715 { 716 boost::system::error_code ec; 717 native_handle_type s = impl_.get_service().release( 718 impl_.get_implementation(), ec); 719 boost::asio::detail::throw_error(ec, "release"); 720 return s; 721 } 722 723 /// Release ownership of the underlying native acceptor. 724 /** 725 * This function causes all outstanding asynchronous accept operations to 726 * finish immediately, and the handlers for cancelled operations will be 727 * passed the boost::asio::error::operation_aborted error. Ownership of the 728 * native acceptor is then transferred to the caller. 729 * 730 * @param ec Set to indicate what error occurred, if any. 731 * 732 * @note This function is unsupported on Windows versions prior to Windows 733 * 8.1, and will fail with boost::asio::error::operation_not_supported on 734 * these platforms. 735 */ 736 #if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ 737 && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) 738 __declspec(deprecated("This function always fails with " 739 "operation_not_supported when used on Windows versions " 740 "prior to Windows 8.1.")) 741 #endif release(boost::system::error_code & ec)742 native_handle_type release(boost::system::error_code& ec) 743 { 744 return impl_.get_service().release(impl_.get_implementation(), ec); 745 } 746 747 /// Get the native acceptor representation. 748 /** 749 * This function may be used to obtain the underlying representation of the 750 * acceptor. This is intended to allow access to native acceptor functionality 751 * that is not otherwise provided. 752 */ native_handle()753 native_handle_type native_handle() 754 { 755 return impl_.get_service().native_handle(impl_.get_implementation()); 756 } 757 758 /// Cancel all asynchronous operations associated with the acceptor. 759 /** 760 * This function causes all outstanding asynchronous connect, send and receive 761 * operations to finish immediately, and the handlers for cancelled operations 762 * will be passed the boost::asio::error::operation_aborted error. 763 * 764 * @throws boost::system::system_error Thrown on failure. 765 */ cancel()766 void cancel() 767 { 768 boost::system::error_code ec; 769 impl_.get_service().cancel(impl_.get_implementation(), ec); 770 boost::asio::detail::throw_error(ec, "cancel"); 771 } 772 773 /// Cancel all asynchronous operations associated with the acceptor. 774 /** 775 * This function causes all outstanding asynchronous connect, send and receive 776 * operations to finish immediately, and the handlers for cancelled operations 777 * will be passed the boost::asio::error::operation_aborted error. 778 * 779 * @param ec Set to indicate what error occurred, if any. 780 */ cancel(boost::system::error_code & ec)781 BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) 782 { 783 impl_.get_service().cancel(impl_.get_implementation(), ec); 784 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 785 } 786 787 /// Set an option on the acceptor. 788 /** 789 * This function is used to set an option on the acceptor. 790 * 791 * @param option The new option value to be set on the acceptor. 792 * 793 * @throws boost::system::system_error Thrown on failure. 794 * 795 * @sa SettableSocketOption @n 796 * boost::asio::socket_base::reuse_address 797 * boost::asio::socket_base::enable_connection_aborted 798 * 799 * @par Example 800 * Setting the SOL_SOCKET/SO_REUSEADDR option: 801 * @code 802 * boost::asio::ip::tcp::acceptor acceptor(my_context); 803 * ... 804 * boost::asio::ip::tcp::acceptor::reuse_address option(true); 805 * acceptor.set_option(option); 806 * @endcode 807 */ 808 template <typename SettableSocketOption> set_option(const SettableSocketOption & option)809 void set_option(const SettableSocketOption& option) 810 { 811 boost::system::error_code ec; 812 impl_.get_service().set_option(impl_.get_implementation(), option, ec); 813 boost::asio::detail::throw_error(ec, "set_option"); 814 } 815 816 /// Set an option on the acceptor. 817 /** 818 * This function is used to set an option on the acceptor. 819 * 820 * @param option The new option value to be set on the acceptor. 821 * 822 * @param ec Set to indicate what error occurred, if any. 823 * 824 * @sa SettableSocketOption @n 825 * boost::asio::socket_base::reuse_address 826 * boost::asio::socket_base::enable_connection_aborted 827 * 828 * @par Example 829 * Setting the SOL_SOCKET/SO_REUSEADDR option: 830 * @code 831 * boost::asio::ip::tcp::acceptor acceptor(my_context); 832 * ... 833 * boost::asio::ip::tcp::acceptor::reuse_address option(true); 834 * boost::system::error_code ec; 835 * acceptor.set_option(option, ec); 836 * if (ec) 837 * { 838 * // An error occurred. 839 * } 840 * @endcode 841 */ 842 template <typename SettableSocketOption> set_option(const SettableSocketOption & option,boost::system::error_code & ec)843 BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option, 844 boost::system::error_code& ec) 845 { 846 impl_.get_service().set_option(impl_.get_implementation(), option, ec); 847 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 848 } 849 850 /// Get an option from the acceptor. 851 /** 852 * This function is used to get the current value of an option on the 853 * acceptor. 854 * 855 * @param option The option value to be obtained from the acceptor. 856 * 857 * @throws boost::system::system_error Thrown on failure. 858 * 859 * @sa GettableSocketOption @n 860 * boost::asio::socket_base::reuse_address 861 * 862 * @par Example 863 * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: 864 * @code 865 * boost::asio::ip::tcp::acceptor acceptor(my_context); 866 * ... 867 * boost::asio::ip::tcp::acceptor::reuse_address option; 868 * acceptor.get_option(option); 869 * bool is_set = option.get(); 870 * @endcode 871 */ 872 template <typename GettableSocketOption> get_option(GettableSocketOption & option) const873 void get_option(GettableSocketOption& option) const 874 { 875 boost::system::error_code ec; 876 impl_.get_service().get_option(impl_.get_implementation(), option, ec); 877 boost::asio::detail::throw_error(ec, "get_option"); 878 } 879 880 /// Get an option from the acceptor. 881 /** 882 * This function is used to get the current value of an option on the 883 * acceptor. 884 * 885 * @param option The option value to be obtained from the acceptor. 886 * 887 * @param ec Set to indicate what error occurred, if any. 888 * 889 * @sa GettableSocketOption @n 890 * boost::asio::socket_base::reuse_address 891 * 892 * @par Example 893 * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: 894 * @code 895 * boost::asio::ip::tcp::acceptor acceptor(my_context); 896 * ... 897 * boost::asio::ip::tcp::acceptor::reuse_address option; 898 * boost::system::error_code ec; 899 * acceptor.get_option(option, ec); 900 * if (ec) 901 * { 902 * // An error occurred. 903 * } 904 * bool is_set = option.get(); 905 * @endcode 906 */ 907 template <typename GettableSocketOption> get_option(GettableSocketOption & option,boost::system::error_code & ec) const908 BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option, 909 boost::system::error_code& ec) const 910 { 911 impl_.get_service().get_option(impl_.get_implementation(), option, ec); 912 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 913 } 914 915 /// Perform an IO control command on the acceptor. 916 /** 917 * This function is used to execute an IO control command on the acceptor. 918 * 919 * @param command The IO control command to be performed on the acceptor. 920 * 921 * @throws boost::system::system_error Thrown on failure. 922 * 923 * @sa IoControlCommand @n 924 * boost::asio::socket_base::non_blocking_io 925 * 926 * @par Example 927 * Getting the number of bytes ready to read: 928 * @code 929 * boost::asio::ip::tcp::acceptor acceptor(my_context); 930 * ... 931 * boost::asio::ip::tcp::acceptor::non_blocking_io command(true); 932 * socket.io_control(command); 933 * @endcode 934 */ 935 template <typename IoControlCommand> io_control(IoControlCommand & command)936 void io_control(IoControlCommand& command) 937 { 938 boost::system::error_code ec; 939 impl_.get_service().io_control(impl_.get_implementation(), command, ec); 940 boost::asio::detail::throw_error(ec, "io_control"); 941 } 942 943 /// Perform an IO control command on the acceptor. 944 /** 945 * This function is used to execute an IO control command on the acceptor. 946 * 947 * @param command The IO control command to be performed on the acceptor. 948 * 949 * @param ec Set to indicate what error occurred, if any. 950 * 951 * @sa IoControlCommand @n 952 * boost::asio::socket_base::non_blocking_io 953 * 954 * @par Example 955 * Getting the number of bytes ready to read: 956 * @code 957 * boost::asio::ip::tcp::acceptor acceptor(my_context); 958 * ... 959 * boost::asio::ip::tcp::acceptor::non_blocking_io command(true); 960 * boost::system::error_code ec; 961 * socket.io_control(command, ec); 962 * if (ec) 963 * { 964 * // An error occurred. 965 * } 966 * @endcode 967 */ 968 template <typename IoControlCommand> io_control(IoControlCommand & command,boost::system::error_code & ec)969 BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, 970 boost::system::error_code& ec) 971 { 972 impl_.get_service().io_control(impl_.get_implementation(), command, ec); 973 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 974 } 975 976 /// Gets the non-blocking mode of the acceptor. 977 /** 978 * @returns @c true if the acceptor's synchronous operations will fail with 979 * boost::asio::error::would_block if they are unable to perform the requested 980 * operation immediately. If @c false, synchronous operations will block 981 * until complete. 982 * 983 * @note The non-blocking mode has no effect on the behaviour of asynchronous 984 * operations. Asynchronous operations will never fail with the error 985 * boost::asio::error::would_block. 986 */ non_blocking() const987 bool non_blocking() const 988 { 989 return impl_.get_service().non_blocking(impl_.get_implementation()); 990 } 991 992 /// Sets the non-blocking mode of the acceptor. 993 /** 994 * @param mode If @c true, the acceptor's synchronous operations will fail 995 * with boost::asio::error::would_block if they are unable to perform the 996 * requested operation immediately. If @c false, synchronous operations will 997 * block until complete. 998 * 999 * @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 */ non_blocking(bool mode)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 */ non_blocking(bool mode,boost::system::error_code & ec)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 */ native_non_blocking() const1046 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 */ native_non_blocking(bool mode)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 */ native_non_blocking(bool mode,boost::system::error_code & ec)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 */ local_endpoint() const1112 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 */ local_endpoint(boost::system::error_code & ec) const1143 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 */ wait(wait_type w)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 */ wait(wait_type w,boost::system::error_code & ec)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. 1201 * 1202 * @param w Specifies the desired acceptor state. 1203 * 1204 * @param handler The handler to be called when the wait operation completes. 1205 * Copies will be made of the handler as required. The function signature of 1206 * the handler must be: 1207 * @code void handler( 1208 * const boost::system::error_code& error // Result of operation 1209 * ); @endcode 1210 * Regardless of whether the asynchronous operation completes immediately or 1211 * not, the handler will not be invoked from within this function. On 1212 * immediate completion, invocation of the handler will be performed in a 1213 * manner equivalent to using boost::asio::post(). 1214 * 1215 * @par Example 1216 * @code 1217 * void wait_handler(const boost::system::error_code& error) 1218 * { 1219 * if (!error) 1220 * { 1221 * // Wait succeeded. 1222 * } 1223 * } 1224 * 1225 * ... 1226 * 1227 * boost::asio::ip::tcp::acceptor acceptor(my_context); 1228 * ... 1229 * acceptor.async_wait( 1230 * boost::asio::ip::tcp::acceptor::wait_read, 1231 * wait_handler); 1232 * @endcode 1233 * 1234 * @par Per-Operation Cancellation 1235 * On POSIX or Windows operating systems, this asynchronous operation supports 1236 * cancellation for the following boost::asio::cancellation_type values: 1237 * 1238 * @li @c cancellation_type::terminal 1239 * 1240 * @li @c cancellation_type::partial 1241 * 1242 * @li @c cancellation_type::total 1243 */ 1244 template < 1245 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code)) 1246 WaitHandler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WaitHandler,void (boost::system::error_code))1247 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WaitHandler, 1248 void (boost::system::error_code)) 1249 async_wait(wait_type w, 1250 BOOST_ASIO_MOVE_ARG(WaitHandler) handler 1251 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) 1252 { 1253 return async_initiate<WaitHandler, void (boost::system::error_code)>( 1254 initiate_async_wait(this), handler, w); 1255 } 1256 1257 #if !defined(BOOST_ASIO_NO_EXTENSIONS) 1258 /// Accept a new connection. 1259 /** 1260 * This function is used to accept a new connection from a peer into the 1261 * given socket. The function call will block until a new connection has been 1262 * accepted successfully or an error occurs. 1263 * 1264 * @param peer The socket into which the new connection will be accepted. 1265 * 1266 * @throws boost::system::system_error Thrown on failure. 1267 * 1268 * @par Example 1269 * @code 1270 * boost::asio::ip::tcp::acceptor acceptor(my_context); 1271 * ... 1272 * boost::asio::ip::tcp::socket socket(my_context); 1273 * acceptor.accept(socket); 1274 * @endcode 1275 */ 1276 template <typename Protocol1, typename Executor1> accept(basic_socket<Protocol1,Executor1> & peer,typename constraint<is_convertible<Protocol,Protocol1>::value>::type=0)1277 void accept(basic_socket<Protocol1, Executor1>& peer, 1278 typename constraint< 1279 is_convertible<Protocol, Protocol1>::value 1280 >::type = 0) 1281 { 1282 boost::system::error_code ec; 1283 impl_.get_service().accept(impl_.get_implementation(), 1284 peer, static_cast<endpoint_type*>(0), ec); 1285 boost::asio::detail::throw_error(ec, "accept"); 1286 } 1287 1288 /// Accept a new connection. 1289 /** 1290 * This function is used to accept a new connection from a peer into the 1291 * given socket. The function call will block until a new connection has been 1292 * accepted successfully or an error occurs. 1293 * 1294 * @param peer The socket into which the new connection will be accepted. 1295 * 1296 * @param ec Set to indicate what error occurred, if any. 1297 * 1298 * @par Example 1299 * @code 1300 * boost::asio::ip::tcp::acceptor acceptor(my_context); 1301 * ... 1302 * boost::asio::ip::tcp::socket socket(my_context); 1303 * boost::system::error_code ec; 1304 * acceptor.accept(socket, ec); 1305 * if (ec) 1306 * { 1307 * // An error occurred. 1308 * } 1309 * @endcode 1310 */ 1311 template <typename Protocol1, typename Executor1> accept(basic_socket<Protocol1,Executor1> & peer,boost::system::error_code & ec,typename constraint<is_convertible<Protocol,Protocol1>::value>::type=0)1312 BOOST_ASIO_SYNC_OP_VOID accept( 1313 basic_socket<Protocol1, Executor1>& peer, boost::system::error_code& ec, 1314 typename constraint< 1315 is_convertible<Protocol, Protocol1>::value 1316 >::type = 0) 1317 { 1318 impl_.get_service().accept(impl_.get_implementation(), 1319 peer, static_cast<endpoint_type*>(0), ec); 1320 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 1321 } 1322 1323 /// Start an asynchronous accept. 1324 /** 1325 * This function is used to asynchronously accept a new connection into a 1326 * socket. The function call always returns immediately. 1327 * 1328 * @param peer The socket into which the new connection will be accepted. 1329 * Ownership of the peer object is retained by the caller, which must 1330 * guarantee that it is valid until the handler is called. 1331 * 1332 * @param handler The handler to be called when the accept operation 1333 * completes. Copies will be made of the handler as required. The function 1334 * signature of the handler must be: 1335 * @code void handler( 1336 * const boost::system::error_code& error // Result of operation. 1337 * ); @endcode 1338 * Regardless of whether the asynchronous operation completes immediately or 1339 * not, the handler will not be invoked from within this function. On 1340 * immediate completion, invocation of the handler will be performed in a 1341 * manner equivalent to using boost::asio::post(). 1342 * 1343 * @par Example 1344 * @code 1345 * void accept_handler(const boost::system::error_code& error) 1346 * { 1347 * if (!error) 1348 * { 1349 * // Accept succeeded. 1350 * } 1351 * } 1352 * 1353 * ... 1354 * 1355 * boost::asio::ip::tcp::acceptor acceptor(my_context); 1356 * ... 1357 * boost::asio::ip::tcp::socket socket(my_context); 1358 * acceptor.async_accept(socket, accept_handler); 1359 * @endcode 1360 * 1361 * @par Per-Operation Cancellation 1362 * On POSIX or Windows operating systems, this asynchronous operation supports 1363 * cancellation for the following boost::asio::cancellation_type values: 1364 * 1365 * @li @c cancellation_type::terminal 1366 * 1367 * @li @c cancellation_type::partial 1368 * 1369 * @li @c cancellation_type::total 1370 */ 1371 template <typename Protocol1, typename Executor1, 1372 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code)) 1373 AcceptHandler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(AcceptHandler,void (boost::system::error_code))1374 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(AcceptHandler, 1375 void (boost::system::error_code)) 1376 async_accept(basic_socket<Protocol1, Executor1>& peer, 1377 BOOST_ASIO_MOVE_ARG(AcceptHandler) handler 1378 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type), 1379 typename constraint< 1380 is_convertible<Protocol, Protocol1>::value 1381 >::type = 0) 1382 { 1383 return async_initiate<AcceptHandler, void (boost::system::error_code)>( 1384 initiate_async_accept(this), handler, 1385 &peer, static_cast<endpoint_type*>(0)); 1386 } 1387 1388 /// Accept a new connection and obtain the endpoint of the peer 1389 /** 1390 * This function is used to accept a new connection from a peer into the 1391 * given socket, and additionally provide the endpoint of the remote peer. 1392 * The function call will block until a new connection has been accepted 1393 * successfully or an error occurs. 1394 * 1395 * @param peer The socket into which the new connection will be accepted. 1396 * 1397 * @param peer_endpoint An endpoint object which will receive the endpoint of 1398 * the remote peer. 1399 * 1400 * @throws boost::system::system_error Thrown on failure. 1401 * 1402 * @par Example 1403 * @code 1404 * boost::asio::ip::tcp::acceptor acceptor(my_context); 1405 * ... 1406 * boost::asio::ip::tcp::socket socket(my_context); 1407 * boost::asio::ip::tcp::endpoint endpoint; 1408 * acceptor.accept(socket, endpoint); 1409 * @endcode 1410 */ 1411 template <typename Executor1> accept(basic_socket<protocol_type,Executor1> & peer,endpoint_type & peer_endpoint)1412 void accept(basic_socket<protocol_type, Executor1>& peer, 1413 endpoint_type& peer_endpoint) 1414 { 1415 boost::system::error_code ec; 1416 impl_.get_service().accept(impl_.get_implementation(), 1417 peer, &peer_endpoint, ec); 1418 boost::asio::detail::throw_error(ec, "accept"); 1419 } 1420 1421 /// Accept a new connection and obtain the endpoint of the peer 1422 /** 1423 * This function is used to accept a new connection from a peer into the 1424 * given socket, and additionally provide the endpoint of the remote peer. 1425 * The function call will block until a new connection has been accepted 1426 * successfully or an error occurs. 1427 * 1428 * @param peer The socket into which the new connection will be accepted. 1429 * 1430 * @param peer_endpoint An endpoint object which will receive the endpoint of 1431 * the remote peer. 1432 * 1433 * @param ec Set to indicate what error occurred, if any. 1434 * 1435 * @par Example 1436 * @code 1437 * boost::asio::ip::tcp::acceptor acceptor(my_context); 1438 * ... 1439 * boost::asio::ip::tcp::socket socket(my_context); 1440 * boost::asio::ip::tcp::endpoint endpoint; 1441 * boost::system::error_code ec; 1442 * acceptor.accept(socket, endpoint, ec); 1443 * if (ec) 1444 * { 1445 * // An error occurred. 1446 * } 1447 * @endcode 1448 */ 1449 template <typename Executor1> accept(basic_socket<protocol_type,Executor1> & peer,endpoint_type & peer_endpoint,boost::system::error_code & ec)1450 BOOST_ASIO_SYNC_OP_VOID accept(basic_socket<protocol_type, Executor1>& peer, 1451 endpoint_type& peer_endpoint, boost::system::error_code& ec) 1452 { 1453 impl_.get_service().accept( 1454 impl_.get_implementation(), peer, &peer_endpoint, ec); 1455 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 1456 } 1457 1458 /// Start an asynchronous accept. 1459 /** 1460 * This function is used to asynchronously accept a new connection into a 1461 * socket, and additionally obtain the endpoint of the remote peer. The 1462 * function call always returns immediately. 1463 * 1464 * @param peer The socket into which the new connection will be accepted. 1465 * Ownership of the peer object is retained by the caller, which must 1466 * guarantee that it is valid until the handler is called. 1467 * 1468 * @param peer_endpoint An endpoint object into which the endpoint of the 1469 * remote peer will be written. Ownership of the peer_endpoint object is 1470 * retained by the caller, which must guarantee that it is valid until the 1471 * handler is called. 1472 * 1473 * @param handler The handler to be called when the accept operation 1474 * completes. Copies will be made of the handler as required. The function 1475 * signature of the handler must be: 1476 * @code void handler( 1477 * const boost::system::error_code& error // Result of operation. 1478 * ); @endcode 1479 * Regardless of whether the asynchronous operation completes immediately or 1480 * not, the handler will not be invoked from within this function. On 1481 * immediate completion, invocation of the handler will be performed in a 1482 * manner equivalent to using boost::asio::post(). 1483 * 1484 * @par Per-Operation Cancellation 1485 * On POSIX or Windows operating systems, this asynchronous operation supports 1486 * cancellation for the following boost::asio::cancellation_type values: 1487 * 1488 * @li @c cancellation_type::terminal 1489 * 1490 * @li @c cancellation_type::partial 1491 * 1492 * @li @c cancellation_type::total 1493 */ 1494 template <typename Executor1, 1495 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code)) 1496 AcceptHandler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(AcceptHandler,void (boost::system::error_code))1497 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(AcceptHandler, 1498 void (boost::system::error_code)) 1499 async_accept(basic_socket<protocol_type, Executor1>& peer, 1500 endpoint_type& peer_endpoint, 1501 BOOST_ASIO_MOVE_ARG(AcceptHandler) handler 1502 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) 1503 { 1504 return async_initiate<AcceptHandler, void (boost::system::error_code)>( 1505 initiate_async_accept(this), handler, &peer, &peer_endpoint); 1506 } 1507 #endif // !defined(BOOST_ASIO_NO_EXTENSIONS) 1508 1509 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) 1510 /// Accept a new connection. 1511 /** 1512 * This function is used to accept a new connection from a peer. The function 1513 * call will block until a new connection has been accepted successfully or 1514 * an error occurs. 1515 * 1516 * This overload requires that the Protocol template parameter satisfy the 1517 * AcceptableProtocol type requirements. 1518 * 1519 * @returns A socket object representing the newly accepted connection. 1520 * 1521 * @throws boost::system::system_error Thrown on failure. 1522 * 1523 * @par Example 1524 * @code 1525 * boost::asio::ip::tcp::acceptor acceptor(my_context); 1526 * ... 1527 * boost::asio::ip::tcp::socket socket(acceptor.accept()); 1528 * @endcode 1529 */ 1530 typename Protocol::socket::template rebind_executor<executor_type>::other accept()1531 accept() 1532 { 1533 boost::system::error_code ec; 1534 typename Protocol::socket::template rebind_executor< 1535 executor_type>::other peer(impl_.get_executor()); 1536 impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); 1537 boost::asio::detail::throw_error(ec, "accept"); 1538 return peer; 1539 } 1540 1541 /// Accept a new connection. 1542 /** 1543 * This function is used to accept a new connection from a peer. The function 1544 * call will block until a new connection has been accepted successfully or 1545 * an error occurs. 1546 * 1547 * This overload requires that the Protocol template parameter satisfy the 1548 * AcceptableProtocol type requirements. 1549 * 1550 * @param ec Set to indicate what error occurred, if any. 1551 * 1552 * @returns On success, a socket object representing the newly accepted 1553 * connection. On error, a socket object where is_open() is false. 1554 * 1555 * @par Example 1556 * @code 1557 * boost::asio::ip::tcp::acceptor acceptor(my_context); 1558 * ... 1559 * boost::asio::ip::tcp::socket socket(acceptor.accept(ec)); 1560 * if (ec) 1561 * { 1562 * // An error occurred. 1563 * } 1564 * @endcode 1565 */ 1566 typename Protocol::socket::template rebind_executor<executor_type>::other accept(boost::system::error_code & ec)1567 accept(boost::system::error_code& ec) 1568 { 1569 typename Protocol::socket::template rebind_executor< 1570 executor_type>::other peer(impl_.get_executor()); 1571 impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); 1572 return peer; 1573 } 1574 1575 /// Start an asynchronous accept. 1576 /** 1577 * This function is used to asynchronously accept a new connection. The 1578 * function call always returns immediately. 1579 * 1580 * This overload requires that the Protocol template parameter satisfy the 1581 * AcceptableProtocol type requirements. 1582 * 1583 * @param handler The handler to be called when the accept operation 1584 * completes. Copies will be made of the handler as required. The function 1585 * signature of the handler must be: 1586 * @code void handler( 1587 * // Result of operation. 1588 * const boost::system::error_code& error, 1589 * // On success, the newly accepted socket. 1590 * typename Protocol::socket::template 1591 * rebind_executor<executor_type>::other peer 1592 * ); @endcode 1593 * Regardless of whether the asynchronous operation completes immediately or 1594 * not, the handler will not be invoked from within this function. On 1595 * immediate completion, invocation of the handler will be performed in a 1596 * manner equivalent to using boost::asio::post(). 1597 * 1598 * @par Example 1599 * @code 1600 * void accept_handler(const boost::system::error_code& error, 1601 * boost::asio::ip::tcp::socket peer) 1602 * { 1603 * if (!error) 1604 * { 1605 * // Accept succeeded. 1606 * } 1607 * } 1608 * 1609 * ... 1610 * 1611 * boost::asio::ip::tcp::acceptor acceptor(my_context); 1612 * ... 1613 * acceptor.async_accept(accept_handler); 1614 * @endcode 1615 * 1616 * @par Per-Operation Cancellation 1617 * On POSIX or Windows operating systems, this asynchronous operation supports 1618 * cancellation for the following boost::asio::cancellation_type values: 1619 * 1620 * @li @c cancellation_type::terminal 1621 * 1622 * @li @c cancellation_type::partial 1623 * 1624 * @li @c cancellation_type::total 1625 */ 1626 template < 1627 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, 1628 typename Protocol::socket::template rebind_executor< 1629 executor_type>::other)) MoveAcceptHandler 1630 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,void (boost::system::error_code,typename Protocol::socket::template rebind_executor<executor_type>::other))1631 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler, 1632 void (boost::system::error_code, 1633 typename Protocol::socket::template 1634 rebind_executor<executor_type>::other)) 1635 async_accept( 1636 BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler 1637 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) 1638 { 1639 return async_initiate<MoveAcceptHandler, 1640 void (boost::system::error_code, typename Protocol::socket::template 1641 rebind_executor<executor_type>::other)>( 1642 initiate_async_move_accept(this), handler, 1643 impl_.get_executor(), static_cast<endpoint_type*>(0), 1644 static_cast<typename Protocol::socket::template 1645 rebind_executor<executor_type>::other*>(0)); 1646 } 1647 1648 /// Accept a new connection. 1649 /** 1650 * This function is used to accept a new connection from a peer. The function 1651 * call will block until a new connection has been accepted successfully or 1652 * an error occurs. 1653 * 1654 * This overload requires that the Protocol template parameter satisfy the 1655 * AcceptableProtocol type requirements. 1656 * 1657 * @param ex The I/O executor object to be used for the newly 1658 * accepted socket. 1659 * 1660 * @returns A socket object representing the newly accepted connection. 1661 * 1662 * @throws boost::system::system_error Thrown on failure. 1663 * 1664 * @par Example 1665 * @code 1666 * boost::asio::ip::tcp::acceptor acceptor(my_context); 1667 * ... 1668 * boost::asio::ip::tcp::socket socket(acceptor.accept()); 1669 * @endcode 1670 */ 1671 template <typename Executor1> 1672 typename Protocol::socket::template rebind_executor<Executor1>::other accept(const Executor1 & ex,typename constraint<is_executor<Executor1>::value||execution::is_executor<Executor1>::value>::type=0)1673 accept(const Executor1& ex, 1674 typename constraint< 1675 is_executor<Executor1>::value 1676 || execution::is_executor<Executor1>::value 1677 >::type = 0) 1678 { 1679 boost::system::error_code ec; 1680 typename Protocol::socket::template 1681 rebind_executor<Executor1>::other peer(ex); 1682 impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); 1683 boost::asio::detail::throw_error(ec, "accept"); 1684 return peer; 1685 } 1686 1687 /// Accept a new connection. 1688 /** 1689 * This function is used to accept a new connection from a peer. The function 1690 * call will block until a new connection has been accepted successfully or 1691 * an error occurs. 1692 * 1693 * This overload requires that the Protocol template parameter satisfy the 1694 * AcceptableProtocol type requirements. 1695 * 1696 * @param context The I/O execution context object to be used for the newly 1697 * accepted socket. 1698 * 1699 * @returns A socket object representing the newly accepted connection. 1700 * 1701 * @throws boost::system::system_error Thrown on failure. 1702 * 1703 * @par Example 1704 * @code 1705 * boost::asio::ip::tcp::acceptor acceptor(my_context); 1706 * ... 1707 * boost::asio::ip::tcp::socket socket(acceptor.accept()); 1708 * @endcode 1709 */ 1710 template <typename ExecutionContext> 1711 typename Protocol::socket::template rebind_executor< 1712 typename ExecutionContext::executor_type>::other accept(ExecutionContext & context,typename constraint<is_convertible<ExecutionContext &,execution_context &>::value>::type=0)1713 accept(ExecutionContext& context, 1714 typename constraint< 1715 is_convertible<ExecutionContext&, execution_context&>::value 1716 >::type = 0) 1717 { 1718 boost::system::error_code ec; 1719 typename Protocol::socket::template rebind_executor< 1720 typename ExecutionContext::executor_type>::other peer(context); 1721 impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); 1722 boost::asio::detail::throw_error(ec, "accept"); 1723 return peer; 1724 } 1725 1726 /// Accept a new connection. 1727 /** 1728 * This function is used to accept a new connection from a peer. The function 1729 * call will block until a new connection has been accepted successfully or 1730 * an error occurs. 1731 * 1732 * This overload requires that the Protocol template parameter satisfy the 1733 * AcceptableProtocol type requirements. 1734 * 1735 * @param ex The I/O executor object to be used for the newly accepted 1736 * socket. 1737 * 1738 * @param ec Set to indicate what error occurred, if any. 1739 * 1740 * @returns On success, a socket object representing the newly accepted 1741 * connection. On error, a socket object where is_open() is false. 1742 * 1743 * @par Example 1744 * @code 1745 * boost::asio::ip::tcp::acceptor acceptor(my_context); 1746 * ... 1747 * boost::asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec)); 1748 * if (ec) 1749 * { 1750 * // An error occurred. 1751 * } 1752 * @endcode 1753 */ 1754 template <typename Executor1> 1755 typename Protocol::socket::template rebind_executor<Executor1>::other accept(const Executor1 & ex,boost::system::error_code & ec,typename constraint<is_executor<Executor1>::value||execution::is_executor<Executor1>::value>::type=0)1756 accept(const Executor1& ex, boost::system::error_code& ec, 1757 typename constraint< 1758 is_executor<Executor1>::value 1759 || execution::is_executor<Executor1>::value 1760 >::type = 0) 1761 { 1762 typename Protocol::socket::template 1763 rebind_executor<Executor1>::other peer(ex); 1764 impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); 1765 return peer; 1766 } 1767 1768 /// Accept a new connection. 1769 /** 1770 * This function is used to accept a new connection from a peer. The function 1771 * call will block until a new connection has been accepted successfully or 1772 * an error occurs. 1773 * 1774 * This overload requires that the Protocol template parameter satisfy the 1775 * AcceptableProtocol type requirements. 1776 * 1777 * @param context The I/O execution context object to be used for the newly 1778 * accepted socket. 1779 * 1780 * @param ec Set to indicate what error occurred, if any. 1781 * 1782 * @returns On success, a socket object representing the newly accepted 1783 * connection. On error, a socket object where is_open() is false. 1784 * 1785 * @par Example 1786 * @code 1787 * boost::asio::ip::tcp::acceptor acceptor(my_context); 1788 * ... 1789 * boost::asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec)); 1790 * if (ec) 1791 * { 1792 * // An error occurred. 1793 * } 1794 * @endcode 1795 */ 1796 template <typename ExecutionContext> 1797 typename Protocol::socket::template rebind_executor< 1798 typename ExecutionContext::executor_type>::other accept(ExecutionContext & context,boost::system::error_code & ec,typename constraint<is_convertible<ExecutionContext &,execution_context &>::value>::type=0)1799 accept(ExecutionContext& context, boost::system::error_code& ec, 1800 typename constraint< 1801 is_convertible<ExecutionContext&, execution_context&>::value 1802 >::type = 0) 1803 { 1804 typename Protocol::socket::template rebind_executor< 1805 typename ExecutionContext::executor_type>::other peer(context); 1806 impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); 1807 return peer; 1808 } 1809 1810 /// Start an asynchronous accept. 1811 /** 1812 * This function is used to asynchronously accept a new connection. The 1813 * function call always returns immediately. 1814 * 1815 * This overload requires that the Protocol template parameter satisfy the 1816 * AcceptableProtocol type requirements. 1817 * 1818 * @param ex The I/O executor object to be used for the newly accepted 1819 * socket. 1820 * 1821 * @param handler The handler to be called when the accept operation 1822 * completes. Copies will be made of the handler as required. The function 1823 * signature of the handler must be: 1824 * @code void handler( 1825 * const boost::system::error_code& error, // Result of operation. 1826 * typename Protocol::socket::template rebind_executor< 1827 * Executor1>::other peer // On success, the newly accepted socket. 1828 * ); @endcode 1829 * Regardless of whether the asynchronous operation completes immediately or 1830 * not, the handler will not be invoked from within this function. On 1831 * immediate completion, invocation of the handler will be performed in a 1832 * manner equivalent to using boost::asio::post(). 1833 * 1834 * @par Example 1835 * @code 1836 * void accept_handler(const boost::system::error_code& error, 1837 * boost::asio::ip::tcp::socket peer) 1838 * { 1839 * if (!error) 1840 * { 1841 * // Accept succeeded. 1842 * } 1843 * } 1844 * 1845 * ... 1846 * 1847 * boost::asio::ip::tcp::acceptor acceptor(my_context); 1848 * ... 1849 * acceptor.async_accept(my_context2, accept_handler); 1850 * @endcode 1851 * 1852 * @par Per-Operation Cancellation 1853 * On POSIX or Windows operating systems, this asynchronous operation supports 1854 * cancellation for the following boost::asio::cancellation_type values: 1855 * 1856 * @li @c cancellation_type::terminal 1857 * 1858 * @li @c cancellation_type::partial 1859 * 1860 * @li @c cancellation_type::total 1861 */ 1862 template <typename Executor1, 1863 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, 1864 typename Protocol::socket::template rebind_executor< 1865 Executor1>::other)) MoveAcceptHandler 1866 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,void (boost::system::error_code,typename Protocol::socket::template rebind_executor<Executor1>::other))1867 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler, 1868 void (boost::system::error_code, 1869 typename Protocol::socket::template rebind_executor< 1870 Executor1>::other)) 1871 async_accept(const Executor1& ex, 1872 BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler 1873 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type), 1874 typename constraint< 1875 is_executor<Executor1>::value 1876 || execution::is_executor<Executor1>::value 1877 >::type = 0) 1878 { 1879 typedef typename Protocol::socket::template rebind_executor< 1880 Executor1>::other other_socket_type; 1881 1882 return async_initiate<MoveAcceptHandler, 1883 void (boost::system::error_code, other_socket_type)>( 1884 initiate_async_move_accept(this), handler, 1885 ex, static_cast<endpoint_type*>(0), 1886 static_cast<other_socket_type*>(0)); 1887 } 1888 1889 /// Start an asynchronous accept. 1890 /** 1891 * This function is used to asynchronously accept a new connection. The 1892 * function call always returns immediately. 1893 * 1894 * This overload requires that the Protocol template parameter satisfy the 1895 * AcceptableProtocol type requirements. 1896 * 1897 * @param context The I/O execution context object to be used for the newly 1898 * accepted socket. 1899 * 1900 * @param handler The handler to be called when the accept operation 1901 * completes. Copies will be made of the handler as required. The function 1902 * signature of the handler must be: 1903 * @code void handler( 1904 * const boost::system::error_code& error, // Result of operation. 1905 * typename Protocol::socket::template rebind_executor< 1906 * typename ExecutionContext::executor_type>::other peer 1907 * // On success, the newly accepted socket. 1908 * ); @endcode 1909 * Regardless of whether the asynchronous operation completes immediately or 1910 * not, the handler will not be invoked from within this function. On 1911 * immediate completion, invocation of the handler will be performed in a 1912 * manner equivalent to using boost::asio::post(). 1913 * 1914 * @par Example 1915 * @code 1916 * void accept_handler(const boost::system::error_code& error, 1917 * boost::asio::ip::tcp::socket peer) 1918 * { 1919 * if (!error) 1920 * { 1921 * // Accept succeeded. 1922 * } 1923 * } 1924 * 1925 * ... 1926 * 1927 * boost::asio::ip::tcp::acceptor acceptor(my_context); 1928 * ... 1929 * acceptor.async_accept(my_context2, accept_handler); 1930 * @endcode 1931 * 1932 * @par Per-Operation Cancellation 1933 * On POSIX or Windows operating systems, this asynchronous operation supports 1934 * cancellation for the following boost::asio::cancellation_type values: 1935 * 1936 * @li @c cancellation_type::terminal 1937 * 1938 * @li @c cancellation_type::partial 1939 * 1940 * @li @c cancellation_type::total 1941 */ 1942 template <typename ExecutionContext, 1943 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, 1944 typename Protocol::socket::template rebind_executor< 1945 typename ExecutionContext::executor_type>::other)) MoveAcceptHandler 1946 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,void (boost::system::error_code,typename Protocol::socket::template rebind_executor<typename ExecutionContext::executor_type>::other))1947 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler, 1948 void (boost::system::error_code, 1949 typename Protocol::socket::template rebind_executor< 1950 typename ExecutionContext::executor_type>::other)) 1951 async_accept(ExecutionContext& context, 1952 BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler 1953 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type), 1954 typename constraint< 1955 is_convertible<ExecutionContext&, execution_context&>::value 1956 >::type = 0) 1957 { 1958 typedef typename Protocol::socket::template rebind_executor< 1959 typename ExecutionContext::executor_type>::other other_socket_type; 1960 1961 return async_initiate<MoveAcceptHandler, 1962 void (boost::system::error_code, other_socket_type)>( 1963 initiate_async_move_accept(this), handler, 1964 context.get_executor(), static_cast<endpoint_type*>(0), 1965 static_cast<other_socket_type*>(0)); 1966 } 1967 1968 /// Accept a new connection. 1969 /** 1970 * This function is used to accept a new connection from a peer. The function 1971 * call will block until a new connection has been accepted successfully or 1972 * an error occurs. 1973 * 1974 * This overload requires that the Protocol template parameter satisfy the 1975 * AcceptableProtocol type requirements. 1976 * 1977 * @param peer_endpoint An endpoint object into which the endpoint of the 1978 * remote peer will be written. 1979 * 1980 * @returns A socket object representing the newly accepted connection. 1981 * 1982 * @throws boost::system::system_error Thrown on failure. 1983 * 1984 * @par Example 1985 * @code 1986 * boost::asio::ip::tcp::acceptor acceptor(my_context); 1987 * ... 1988 * boost::asio::ip::tcp::endpoint endpoint; 1989 * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint)); 1990 * @endcode 1991 */ 1992 typename Protocol::socket::template rebind_executor<executor_type>::other accept(endpoint_type & peer_endpoint)1993 accept(endpoint_type& peer_endpoint) 1994 { 1995 boost::system::error_code ec; 1996 typename Protocol::socket::template rebind_executor< 1997 executor_type>::other peer(impl_.get_executor()); 1998 impl_.get_service().accept(impl_.get_implementation(), 1999 peer, &peer_endpoint, ec); 2000 boost::asio::detail::throw_error(ec, "accept"); 2001 return peer; 2002 } 2003 2004 /// Accept a new connection. 2005 /** 2006 * This function is used to accept a new connection from a peer. The function 2007 * call will block until a new connection has been accepted successfully or 2008 * an error occurs. 2009 * 2010 * This overload requires that the Protocol template parameter satisfy the 2011 * AcceptableProtocol type requirements. 2012 * 2013 * @param peer_endpoint An endpoint object into which the endpoint of the 2014 * remote peer will be written. 2015 * 2016 * @param ec Set to indicate what error occurred, if any. 2017 * 2018 * @returns On success, a socket object representing the newly accepted 2019 * connection. On error, a socket object where is_open() is false. 2020 * 2021 * @par Example 2022 * @code 2023 * boost::asio::ip::tcp::acceptor acceptor(my_context); 2024 * ... 2025 * boost::asio::ip::tcp::endpoint endpoint; 2026 * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint, ec)); 2027 * if (ec) 2028 * { 2029 * // An error occurred. 2030 * } 2031 * @endcode 2032 */ 2033 typename Protocol::socket::template rebind_executor<executor_type>::other accept(endpoint_type & peer_endpoint,boost::system::error_code & ec)2034 accept(endpoint_type& peer_endpoint, boost::system::error_code& ec) 2035 { 2036 typename Protocol::socket::template rebind_executor< 2037 executor_type>::other peer(impl_.get_executor()); 2038 impl_.get_service().accept(impl_.get_implementation(), 2039 peer, &peer_endpoint, ec); 2040 return peer; 2041 } 2042 2043 /// Start an asynchronous accept. 2044 /** 2045 * This function is used to asynchronously accept a new connection. The 2046 * function call always returns immediately. 2047 * 2048 * This overload requires that the Protocol template parameter satisfy the 2049 * AcceptableProtocol type requirements. 2050 * 2051 * @param peer_endpoint An endpoint object into which the endpoint of the 2052 * remote peer will be written. Ownership of the peer_endpoint object is 2053 * retained by the caller, which must guarantee that it is valid until the 2054 * handler is called. 2055 * 2056 * @param handler The handler to be called when the accept operation 2057 * completes. Copies will be made of the handler as required. The function 2058 * signature of the handler must be: 2059 * @code void handler( 2060 * // Result of operation. 2061 * const boost::system::error_code& error, 2062 * // On success, the newly accepted socket. 2063 * typename Protocol::socket::template 2064 * rebind_executor<executor_type>::other peer 2065 * ); @endcode 2066 * Regardless of whether the asynchronous operation completes immediately or 2067 * not, the handler will not be invoked from within this function. On 2068 * immediate completion, invocation of the handler will be performed in a 2069 * manner equivalent to using boost::asio::post(). 2070 * 2071 * @par Example 2072 * @code 2073 * void accept_handler(const boost::system::error_code& error, 2074 * boost::asio::ip::tcp::socket peer) 2075 * { 2076 * if (!error) 2077 * { 2078 * // Accept succeeded. 2079 * } 2080 * } 2081 * 2082 * ... 2083 * 2084 * boost::asio::ip::tcp::acceptor acceptor(my_context); 2085 * ... 2086 * boost::asio::ip::tcp::endpoint endpoint; 2087 * acceptor.async_accept(endpoint, accept_handler); 2088 * @endcode 2089 * 2090 * @par Per-Operation Cancellation 2091 * On POSIX or Windows operating systems, this asynchronous operation supports 2092 * cancellation for the following boost::asio::cancellation_type values: 2093 * 2094 * @li @c cancellation_type::terminal 2095 * 2096 * @li @c cancellation_type::partial 2097 * 2098 * @li @c cancellation_type::total 2099 */ 2100 template < 2101 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, 2102 typename Protocol::socket::template rebind_executor< 2103 executor_type>::other)) MoveAcceptHandler 2104 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,void (boost::system::error_code,typename Protocol::socket::template rebind_executor<executor_type>::other))2105 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler, 2106 void (boost::system::error_code, 2107 typename Protocol::socket::template 2108 rebind_executor<executor_type>::other)) 2109 async_accept(endpoint_type& peer_endpoint, 2110 BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler 2111 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) 2112 { 2113 return async_initiate<MoveAcceptHandler, 2114 void (boost::system::error_code, typename Protocol::socket::template 2115 rebind_executor<executor_type>::other)>( 2116 initiate_async_move_accept(this), handler, 2117 impl_.get_executor(), &peer_endpoint, 2118 static_cast<typename Protocol::socket::template 2119 rebind_executor<executor_type>::other*>(0)); 2120 } 2121 2122 /// Accept a new connection. 2123 /** 2124 * This function is used to accept a new connection from a peer. The function 2125 * call will block until a new connection has been accepted successfully or 2126 * an error occurs. 2127 * 2128 * This overload requires that the Protocol template parameter satisfy the 2129 * AcceptableProtocol type requirements. 2130 * 2131 * @param ex The I/O executor object to be used for the newly accepted 2132 * socket. 2133 * 2134 * @param peer_endpoint An endpoint object into which the endpoint of the 2135 * remote peer will be written. 2136 * 2137 * @returns A socket object representing the newly accepted connection. 2138 * 2139 * @throws boost::system::system_error Thrown on failure. 2140 * 2141 * @par Example 2142 * @code 2143 * boost::asio::ip::tcp::acceptor acceptor(my_context); 2144 * ... 2145 * boost::asio::ip::tcp::endpoint endpoint; 2146 * boost::asio::ip::tcp::socket socket( 2147 * acceptor.accept(my_context2, endpoint)); 2148 * @endcode 2149 */ 2150 template <typename Executor1> 2151 typename Protocol::socket::template rebind_executor<Executor1>::other accept(const Executor1 & ex,endpoint_type & peer_endpoint,typename constraint<is_executor<Executor1>::value||execution::is_executor<Executor1>::value>::type=0)2152 accept(const Executor1& ex, endpoint_type& peer_endpoint, 2153 typename constraint< 2154 is_executor<Executor1>::value 2155 || execution::is_executor<Executor1>::value 2156 >::type = 0) 2157 { 2158 boost::system::error_code ec; 2159 typename Protocol::socket::template 2160 rebind_executor<Executor1>::other peer(ex); 2161 impl_.get_service().accept(impl_.get_implementation(), 2162 peer, &peer_endpoint, ec); 2163 boost::asio::detail::throw_error(ec, "accept"); 2164 return peer; 2165 } 2166 2167 /// Accept a new connection. 2168 /** 2169 * This function is used to accept a new connection from a peer. The function 2170 * call will block until a new connection has been accepted successfully or 2171 * an error occurs. 2172 * 2173 * This overload requires that the Protocol template parameter satisfy the 2174 * AcceptableProtocol type requirements. 2175 * 2176 * @param context The I/O execution context object to be used for the newly 2177 * accepted socket. 2178 * 2179 * @param peer_endpoint An endpoint object into which the endpoint of the 2180 * remote peer will be written. 2181 * 2182 * @returns A socket object representing the newly accepted connection. 2183 * 2184 * @throws boost::system::system_error Thrown on failure. 2185 * 2186 * @par Example 2187 * @code 2188 * boost::asio::ip::tcp::acceptor acceptor(my_context); 2189 * ... 2190 * boost::asio::ip::tcp::endpoint endpoint; 2191 * boost::asio::ip::tcp::socket socket( 2192 * acceptor.accept(my_context2, endpoint)); 2193 * @endcode 2194 */ 2195 template <typename ExecutionContext> 2196 typename Protocol::socket::template rebind_executor< 2197 typename ExecutionContext::executor_type>::other accept(ExecutionContext & context,endpoint_type & peer_endpoint,typename constraint<is_convertible<ExecutionContext &,execution_context &>::value>::type=0)2198 accept(ExecutionContext& context, endpoint_type& peer_endpoint, 2199 typename constraint< 2200 is_convertible<ExecutionContext&, execution_context&>::value 2201 >::type = 0) 2202 { 2203 boost::system::error_code ec; 2204 typename Protocol::socket::template rebind_executor< 2205 typename ExecutionContext::executor_type>::other peer(context); 2206 impl_.get_service().accept(impl_.get_implementation(), 2207 peer, &peer_endpoint, ec); 2208 boost::asio::detail::throw_error(ec, "accept"); 2209 return peer; 2210 } 2211 2212 /// Accept a new connection. 2213 /** 2214 * This function is used to accept a new connection from a peer. The function 2215 * call will block until a new connection has been accepted successfully or 2216 * an error occurs. 2217 * 2218 * This overload requires that the Protocol template parameter satisfy the 2219 * AcceptableProtocol type requirements. 2220 * 2221 * @param ex The I/O executor object to be used for the newly accepted 2222 * socket. 2223 * 2224 * @param peer_endpoint An endpoint object into which the endpoint of the 2225 * remote peer will be written. 2226 * 2227 * @param ec Set to indicate what error occurred, if any. 2228 * 2229 * @returns On success, a socket object representing the newly accepted 2230 * connection. On error, a socket object where is_open() is false. 2231 * 2232 * @par Example 2233 * @code 2234 * boost::asio::ip::tcp::acceptor acceptor(my_context); 2235 * ... 2236 * boost::asio::ip::tcp::endpoint endpoint; 2237 * boost::asio::ip::tcp::socket socket( 2238 * acceptor.accept(my_context2, endpoint, ec)); 2239 * if (ec) 2240 * { 2241 * // An error occurred. 2242 * } 2243 * @endcode 2244 */ 2245 template <typename Executor1> 2246 typename Protocol::socket::template rebind_executor<Executor1>::other accept(const executor_type & ex,endpoint_type & peer_endpoint,boost::system::error_code & ec,typename constraint<is_executor<Executor1>::value||execution::is_executor<Executor1>::value>::type=0)2247 accept(const executor_type& ex, 2248 endpoint_type& peer_endpoint, boost::system::error_code& ec, 2249 typename constraint< 2250 is_executor<Executor1>::value 2251 || execution::is_executor<Executor1>::value 2252 >::type = 0) 2253 { 2254 typename Protocol::socket::template 2255 rebind_executor<Executor1>::other peer(ex); 2256 impl_.get_service().accept(impl_.get_implementation(), 2257 peer, &peer_endpoint, ec); 2258 return peer; 2259 } 2260 2261 /// Accept a new connection. 2262 /** 2263 * This function is used to accept a new connection from a peer. The function 2264 * call will block until a new connection has been accepted successfully or 2265 * an error occurs. 2266 * 2267 * This overload requires that the Protocol template parameter satisfy the 2268 * AcceptableProtocol type requirements. 2269 * 2270 * @param context The I/O execution context object to be used for the newly 2271 * accepted socket. 2272 * 2273 * @param peer_endpoint An endpoint object into which the endpoint of the 2274 * remote peer will be written. 2275 * 2276 * @param ec Set to indicate what error occurred, if any. 2277 * 2278 * @returns On success, a socket object representing the newly accepted 2279 * connection. On error, a socket object where is_open() is false. 2280 * 2281 * @par Example 2282 * @code 2283 * boost::asio::ip::tcp::acceptor acceptor(my_context); 2284 * ... 2285 * boost::asio::ip::tcp::endpoint endpoint; 2286 * boost::asio::ip::tcp::socket socket( 2287 * acceptor.accept(my_context2, endpoint, ec)); 2288 * if (ec) 2289 * { 2290 * // An error occurred. 2291 * } 2292 * @endcode 2293 */ 2294 template <typename ExecutionContext> 2295 typename Protocol::socket::template rebind_executor< 2296 typename ExecutionContext::executor_type>::other accept(ExecutionContext & context,endpoint_type & peer_endpoint,boost::system::error_code & ec,typename constraint<is_convertible<ExecutionContext &,execution_context &>::value>::type=0)2297 accept(ExecutionContext& context, 2298 endpoint_type& peer_endpoint, boost::system::error_code& ec, 2299 typename constraint< 2300 is_convertible<ExecutionContext&, execution_context&>::value 2301 >::type = 0) 2302 { 2303 typename Protocol::socket::template rebind_executor< 2304 typename ExecutionContext::executor_type>::other peer(context); 2305 impl_.get_service().accept(impl_.get_implementation(), 2306 peer, &peer_endpoint, ec); 2307 return peer; 2308 } 2309 2310 /// Start an asynchronous accept. 2311 /** 2312 * This function is used to asynchronously accept a new connection. The 2313 * function call always returns immediately. 2314 * 2315 * This overload requires that the Protocol template parameter satisfy the 2316 * AcceptableProtocol type requirements. 2317 * 2318 * @param ex The I/O executor object to be used for the newly accepted 2319 * socket. 2320 * 2321 * @param peer_endpoint An endpoint object into which the endpoint of the 2322 * remote peer will be written. Ownership of the peer_endpoint object is 2323 * retained by the caller, which must guarantee that it is valid until the 2324 * handler is called. 2325 * 2326 * @param handler The handler to be called when the accept operation 2327 * completes. Copies will be made of the handler as required. The function 2328 * signature of the handler must be: 2329 * @code void handler( 2330 * const boost::system::error_code& error, // Result of operation. 2331 * typename Protocol::socket::template rebind_executor< 2332 * Executor1>::other peer // On success, the newly accepted socket. 2333 * ); @endcode 2334 * Regardless of whether the asynchronous operation completes immediately or 2335 * not, the handler will not be invoked from within this function. On 2336 * immediate completion, invocation of the handler will be performed in a 2337 * manner equivalent to using boost::asio::post(). 2338 * 2339 * @par Example 2340 * @code 2341 * void accept_handler(const boost::system::error_code& error, 2342 * boost::asio::ip::tcp::socket peer) 2343 * { 2344 * if (!error) 2345 * { 2346 * // Accept succeeded. 2347 * } 2348 * } 2349 * 2350 * ... 2351 * 2352 * boost::asio::ip::tcp::acceptor acceptor(my_context); 2353 * ... 2354 * boost::asio::ip::tcp::endpoint endpoint; 2355 * acceptor.async_accept(my_context2, endpoint, accept_handler); 2356 * @endcode 2357 * 2358 * @par Per-Operation Cancellation 2359 * On POSIX or Windows operating systems, this asynchronous operation supports 2360 * cancellation for the following boost::asio::cancellation_type values: 2361 * 2362 * @li @c cancellation_type::terminal 2363 * 2364 * @li @c cancellation_type::partial 2365 * 2366 * @li @c cancellation_type::total 2367 */ 2368 template <typename Executor1, 2369 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, 2370 typename Protocol::socket::template rebind_executor< 2371 Executor1>::other)) MoveAcceptHandler 2372 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,void (boost::system::error_code,typename Protocol::socket::template rebind_executor<Executor1>::other))2373 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler, 2374 void (boost::system::error_code, 2375 typename Protocol::socket::template rebind_executor< 2376 Executor1>::other)) 2377 async_accept(const Executor1& ex, endpoint_type& peer_endpoint, 2378 BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler 2379 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type), 2380 typename constraint< 2381 is_executor<Executor1>::value 2382 || execution::is_executor<Executor1>::value 2383 >::type = 0) 2384 { 2385 typedef typename Protocol::socket::template rebind_executor< 2386 Executor1>::other other_socket_type; 2387 2388 return async_initiate<MoveAcceptHandler, 2389 void (boost::system::error_code, other_socket_type)>( 2390 initiate_async_move_accept(this), handler, 2391 ex, &peer_endpoint, 2392 static_cast<other_socket_type*>(0)); 2393 } 2394 2395 /// Start an asynchronous accept. 2396 /** 2397 * This function is used to asynchronously accept a new connection. The 2398 * function call always returns immediately. 2399 * 2400 * This overload requires that the Protocol template parameter satisfy the 2401 * AcceptableProtocol type requirements. 2402 * 2403 * @param context The I/O execution context object to be used for the newly 2404 * accepted socket. 2405 * 2406 * @param peer_endpoint An endpoint object into which the endpoint of the 2407 * remote peer will be written. Ownership of the peer_endpoint object is 2408 * retained by the caller, which must guarantee that it is valid until the 2409 * handler is called. 2410 * 2411 * @param handler The handler to be called when the accept operation 2412 * completes. Copies will be made of the handler as required. The function 2413 * signature of the handler must be: 2414 * @code void handler( 2415 * const boost::system::error_code& error, // Result of operation. 2416 * typename Protocol::socket::template rebind_executor< 2417 * typename ExecutionContext::executor_type>::other peer 2418 * // On success, the newly accepted socket. 2419 * ); @endcode 2420 * Regardless of whether the asynchronous operation completes immediately or 2421 * not, the handler will not be invoked from within this function. On 2422 * immediate completion, invocation of the handler will be performed in a 2423 * manner equivalent to using boost::asio::post(). 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 ExecutionContext, 2455 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, 2456 typename Protocol::socket::template rebind_executor< 2457 typename ExecutionContext::executor_type>::other)) MoveAcceptHandler 2458 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,void (boost::system::error_code,typename Protocol::socket::template rebind_executor<typename ExecutionContext::executor_type>::other))2459 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler, 2460 void (boost::system::error_code, 2461 typename Protocol::socket::template rebind_executor< 2462 typename ExecutionContext::executor_type>::other)) 2463 async_accept(ExecutionContext& context, 2464 endpoint_type& peer_endpoint, 2465 BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler 2466 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type), 2467 typename constraint< 2468 is_convertible<ExecutionContext&, execution_context&>::value 2469 >::type = 0) 2470 { 2471 typedef typename Protocol::socket::template rebind_executor< 2472 typename ExecutionContext::executor_type>::other other_socket_type; 2473 2474 return async_initiate<MoveAcceptHandler, 2475 void (boost::system::error_code, other_socket_type)>( 2476 initiate_async_move_accept(this), handler, 2477 context.get_executor(), &peer_endpoint, 2478 static_cast<other_socket_type*>(0)); 2479 } 2480 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) 2481 2482 private: 2483 // Disallow copying and assignment. 2484 basic_socket_acceptor(const basic_socket_acceptor&) BOOST_ASIO_DELETED; 2485 basic_socket_acceptor& operator=( 2486 const basic_socket_acceptor&) BOOST_ASIO_DELETED; 2487 2488 class initiate_async_wait 2489 { 2490 public: 2491 typedef Executor executor_type; 2492 initiate_async_wait(basic_socket_acceptor * self)2493 explicit initiate_async_wait(basic_socket_acceptor* self) 2494 : self_(self) 2495 { 2496 } 2497 get_executor() const2498 executor_type get_executor() const BOOST_ASIO_NOEXCEPT 2499 { 2500 return self_->get_executor(); 2501 } 2502 2503 template <typename WaitHandler> operator ()(BOOST_ASIO_MOVE_ARG (WaitHandler)handler,wait_type w) const2504 void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, wait_type w) const 2505 { 2506 // If you get an error on the following line it means that your handler 2507 // does not meet the documented type requirements for a WaitHandler. 2508 BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; 2509 2510 detail::non_const_lvalue<WaitHandler> handler2(handler); 2511 self_->impl_.get_service().async_wait( 2512 self_->impl_.get_implementation(), w, 2513 handler2.value, self_->impl_.get_executor()); 2514 } 2515 2516 private: 2517 basic_socket_acceptor* self_; 2518 }; 2519 2520 class initiate_async_accept 2521 { 2522 public: 2523 typedef Executor executor_type; 2524 initiate_async_accept(basic_socket_acceptor * self)2525 explicit initiate_async_accept(basic_socket_acceptor* self) 2526 : self_(self) 2527 { 2528 } 2529 get_executor() const2530 executor_type get_executor() const BOOST_ASIO_NOEXCEPT 2531 { 2532 return self_->get_executor(); 2533 } 2534 2535 template <typename AcceptHandler, typename Protocol1, typename Executor1> operator ()(BOOST_ASIO_MOVE_ARG (AcceptHandler)handler,basic_socket<Protocol1,Executor1> * peer,endpoint_type * peer_endpoint) const2536 void operator()(BOOST_ASIO_MOVE_ARG(AcceptHandler) handler, 2537 basic_socket<Protocol1, Executor1>* peer, 2538 endpoint_type* peer_endpoint) const 2539 { 2540 // If you get an error on the following line it means that your handler 2541 // does not meet the documented type requirements for a AcceptHandler. 2542 BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check; 2543 2544 detail::non_const_lvalue<AcceptHandler> handler2(handler); 2545 self_->impl_.get_service().async_accept( 2546 self_->impl_.get_implementation(), *peer, peer_endpoint, 2547 handler2.value, self_->impl_.get_executor()); 2548 } 2549 2550 private: 2551 basic_socket_acceptor* self_; 2552 }; 2553 2554 class initiate_async_move_accept 2555 { 2556 public: 2557 typedef Executor executor_type; 2558 initiate_async_move_accept(basic_socket_acceptor * self)2559 explicit initiate_async_move_accept(basic_socket_acceptor* self) 2560 : self_(self) 2561 { 2562 } 2563 get_executor() const2564 executor_type get_executor() const BOOST_ASIO_NOEXCEPT 2565 { 2566 return self_->get_executor(); 2567 } 2568 2569 template <typename MoveAcceptHandler, typename Executor1, typename Socket> operator ()(BOOST_ASIO_MOVE_ARG (MoveAcceptHandler)handler,const Executor1 & peer_ex,endpoint_type * peer_endpoint,Socket *) const2570 void operator()(BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, 2571 const Executor1& peer_ex, endpoint_type* peer_endpoint, Socket*) const 2572 { 2573 // If you get an error on the following line it means that your handler 2574 // does not meet the documented type requirements for a MoveAcceptHandler. 2575 BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( 2576 MoveAcceptHandler, handler, Socket) type_check; 2577 2578 detail::non_const_lvalue<MoveAcceptHandler> handler2(handler); 2579 self_->impl_.get_service().async_move_accept( 2580 self_->impl_.get_implementation(), peer_ex, peer_endpoint, 2581 handler2.value, self_->impl_.get_executor()); 2582 } 2583 2584 private: 2585 basic_socket_acceptor* self_; 2586 }; 2587 2588 #if defined(BOOST_ASIO_WINDOWS_RUNTIME) 2589 detail::io_object_impl< 2590 detail::null_socket_service<Protocol>, Executor> impl_; 2591 #elif defined(BOOST_ASIO_HAS_IOCP) 2592 detail::io_object_impl< 2593 detail::win_iocp_socket_service<Protocol>, Executor> impl_; 2594 #elif defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT) 2595 detail::io_object_impl< 2596 detail::io_uring_socket_service<Protocol>, Executor> impl_; 2597 #else 2598 detail::io_object_impl< 2599 detail::reactive_socket_service<Protocol>, Executor> impl_; 2600 #endif 2601 }; 2602 2603 } // namespace asio 2604 } // namespace boost 2605 2606 #include <boost/asio/detail/pop_options.hpp> 2607 2608 #endif // BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_HPP 2609