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

source code of boost/libs/asio/include/boost/asio/basic_socket_acceptor.hpp