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