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