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