]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/asio/basic_socket_acceptor.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / asio / basic_socket_acceptor.hpp
1 //
2 // basic_socket_acceptor.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 //
10
11 #ifndef BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_HPP
12 #define BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_HPP
13
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17
18 #include <boost/asio/detail/config.hpp>
19 #include <boost/asio/any_io_executor.hpp>
20 #include <boost/asio/basic_socket.hpp>
21 #include <boost/asio/detail/handler_type_requirements.hpp>
22 #include <boost/asio/detail/io_object_impl.hpp>
23 #include <boost/asio/detail/non_const_lvalue.hpp>
24 #include <boost/asio/detail/throw_error.hpp>
25 #include <boost/asio/detail/type_traits.hpp>
26 #include <boost/asio/error.hpp>
27 #include <boost/asio/execution_context.hpp>
28 #include <boost/asio/socket_base.hpp>
29
30 #if defined(BOOST_ASIO_WINDOWS_RUNTIME)
31 # include <boost/asio/detail/null_socket_service.hpp>
32 #elif defined(BOOST_ASIO_HAS_IOCP)
33 # include <boost/asio/detail/win_iocp_socket_service.hpp>
34 #elif defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
35 # include <boost/asio/detail/io_uring_socket_service.hpp>
36 #else
37 # include <boost/asio/detail/reactive_socket_service.hpp>
38 #endif
39
40 #if defined(BOOST_ASIO_HAS_MOVE)
41 # include <utility>
42 #endif // defined(BOOST_ASIO_HAS_MOVE)
43
44 #include <boost/asio/detail/push_options.hpp>
45
46 namespace boost {
47 namespace asio {
48
49 #if !defined(BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL)
50 #define BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL
51
52 // Forward declaration with defaulted arguments.
53 template <typename Protocol, typename Executor = any_io_executor>
54 class basic_socket_acceptor;
55
56 #endif // !defined(BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL)
57
58 /// Provides the ability to accept new connections.
59 /**
60 * The basic_socket_acceptor class template is used for accepting new socket
61 * connections.
62 *
63 * @par Thread Safety
64 * @e Distinct @e objects: Safe.@n
65 * @e Shared @e objects: Unsafe.
66 *
67 * Synchronous @c accept operations are thread safe, if the underlying
68 * operating system calls are also thread safe. This means that it is permitted
69 * to perform concurrent calls to synchronous @c accept operations on a single
70 * socket object. Other synchronous operations, such as @c open or @c close, are
71 * not thread safe.
72 *
73 * @par Example
74 * Opening a socket acceptor with the SO_REUSEADDR option enabled:
75 * @code
76 * boost::asio::ip::tcp::acceptor acceptor(my_context);
77 * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), port);
78 * acceptor.open(endpoint.protocol());
79 * acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
80 * acceptor.bind(endpoint);
81 * acceptor.listen();
82 * @endcode
83 */
84 template <typename Protocol, typename Executor>
85 class basic_socket_acceptor
86 : public socket_base
87 {
88 public:
89 /// The type of the executor associated with the object.
90 typedef Executor executor_type;
91
92 /// Rebinds the acceptor type to another executor.
93 template <typename Executor1>
94 struct rebind_executor
95 {
96 /// The socket type when rebound to the specified executor.
97 typedef basic_socket_acceptor<Protocol, Executor1> other;
98 };
99
100 /// The native representation of an acceptor.
101 #if defined(GENERATING_DOCUMENTATION)
102 typedef implementation_defined native_handle_type;
103 #elif defined(BOOST_ASIO_WINDOWS_RUNTIME)
104 typedef typename detail::null_socket_service<
105 Protocol>::native_handle_type native_handle_type;
106 #elif defined(BOOST_ASIO_HAS_IOCP)
107 typedef typename detail::win_iocp_socket_service<
108 Protocol>::native_handle_type native_handle_type;
109 #elif defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
110 typedef typename detail::io_uring_socket_service<
111 Protocol>::native_handle_type native_handle_type;
112 #else
113 typedef typename detail::reactive_socket_service<
114 Protocol>::native_handle_type native_handle_type;
115 #endif
116
117 /// The protocol type.
118 typedef Protocol protocol_type;
119
120 /// The endpoint type.
121 typedef typename Protocol::endpoint endpoint_type;
122
123 /// Construct an acceptor without opening it.
124 /**
125 * This constructor creates an acceptor without opening it to listen for new
126 * connections. The open() function must be called before the acceptor can
127 * accept new socket connections.
128 *
129 * @param ex The I/O executor that the acceptor will use, by default, to
130 * dispatch handlers for any asynchronous operations performed on the
131 * acceptor.
132 */
133 explicit basic_socket_acceptor(const executor_type& ex)
134 : impl_(0, ex)
135 {
136 }
137
138 /// Construct an acceptor without opening it.
139 /**
140 * This constructor creates an acceptor without opening it to listen for new
141 * connections. The open() function must be called before the acceptor can
142 * accept new socket connections.
143 *
144 * @param context An execution context which provides the I/O executor that
145 * the acceptor will use, by default, to dispatch handlers for any
146 * asynchronous operations performed on the acceptor.
147 */
148 template <typename ExecutionContext>
149 explicit basic_socket_acceptor(ExecutionContext& context,
150 typename constraint<
151 is_convertible<ExecutionContext&, execution_context&>::value
152 >::type = 0)
153 : impl_(0, 0, context)
154 {
155 }
156
157 /// Construct an open acceptor.
158 /**
159 * This constructor creates an acceptor and automatically opens it.
160 *
161 * @param ex The I/O executor that the acceptor will use, by default, to
162 * dispatch handlers for any asynchronous operations performed on the
163 * acceptor.
164 *
165 * @param protocol An object specifying protocol parameters to be used.
166 *
167 * @throws boost::system::system_error Thrown on failure.
168 */
169 basic_socket_acceptor(const executor_type& ex, const protocol_type& protocol)
170 : impl_(0, ex)
171 {
172 boost::system::error_code ec;
173 impl_.get_service().open(impl_.get_implementation(), protocol, ec);
174 boost::asio::detail::throw_error(ec, "open");
175 }
176
177 /// Construct an open acceptor.
178 /**
179 * This constructor creates an acceptor and automatically opens it.
180 *
181 * @param context An execution context which provides the I/O executor that
182 * the acceptor will use, by default, to dispatch handlers for any
183 * asynchronous operations performed on the acceptor.
184 *
185 * @param protocol An object specifying protocol parameters to be used.
186 *
187 * @throws boost::system::system_error Thrown on failure.
188 */
189 template <typename ExecutionContext>
190 basic_socket_acceptor(ExecutionContext& context,
191 const protocol_type& protocol,
192 typename constraint<
193 is_convertible<ExecutionContext&, execution_context&>::value,
194 defaulted_constraint
195 >::type = defaulted_constraint())
196 : impl_(0, 0, context)
197 {
198 boost::system::error_code ec;
199 impl_.get_service().open(impl_.get_implementation(), protocol, ec);
200 boost::asio::detail::throw_error(ec, "open");
201 }
202
203 /// Construct an acceptor opened on the given endpoint.
204 /**
205 * This constructor creates an acceptor and automatically opens it to listen
206 * for new connections on the specified endpoint.
207 *
208 * @param ex The I/O executor that the acceptor will use, by default, to
209 * dispatch handlers for any asynchronous operations performed on the
210 * acceptor.
211 *
212 * @param endpoint An endpoint on the local machine on which the acceptor
213 * will listen for new connections.
214 *
215 * @param reuse_addr Whether the constructor should set the socket option
216 * socket_base::reuse_address.
217 *
218 * @throws boost::system::system_error Thrown on failure.
219 *
220 * @note This constructor is equivalent to the following code:
221 * @code
222 * basic_socket_acceptor<Protocol> acceptor(my_context);
223 * acceptor.open(endpoint.protocol());
224 * if (reuse_addr)
225 * acceptor.set_option(socket_base::reuse_address(true));
226 * acceptor.bind(endpoint);
227 * acceptor.listen();
228 * @endcode
229 */
230 basic_socket_acceptor(const executor_type& ex,
231 const endpoint_type& endpoint, bool reuse_addr = true)
232 : impl_(0, ex)
233 {
234 boost::system::error_code ec;
235 const protocol_type protocol = endpoint.protocol();
236 impl_.get_service().open(impl_.get_implementation(), protocol, ec);
237 boost::asio::detail::throw_error(ec, "open");
238 if (reuse_addr)
239 {
240 impl_.get_service().set_option(impl_.get_implementation(),
241 socket_base::reuse_address(true), ec);
242 boost::asio::detail::throw_error(ec, "set_option");
243 }
244 impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
245 boost::asio::detail::throw_error(ec, "bind");
246 impl_.get_service().listen(impl_.get_implementation(),
247 socket_base::max_listen_connections, ec);
248 boost::asio::detail::throw_error(ec, "listen");
249 }
250
251 /// Construct an acceptor opened on the given endpoint.
252 /**
253 * This constructor creates an acceptor and automatically opens it to listen
254 * for new connections on the specified endpoint.
255 *
256 * @param context An execution context which provides the I/O executor that
257 * the acceptor will use, by default, to dispatch handlers for any
258 * asynchronous operations performed on the acceptor.
259 *
260 * @param endpoint An endpoint on the local machine on which the acceptor
261 * will listen for new connections.
262 *
263 * @param reuse_addr Whether the constructor should set the socket option
264 * socket_base::reuse_address.
265 *
266 * @throws boost::system::system_error Thrown on failure.
267 *
268 * @note This constructor is equivalent to the following code:
269 * @code
270 * basic_socket_acceptor<Protocol> acceptor(my_context);
271 * acceptor.open(endpoint.protocol());
272 * if (reuse_addr)
273 * acceptor.set_option(socket_base::reuse_address(true));
274 * acceptor.bind(endpoint);
275 * acceptor.listen();
276 * @endcode
277 */
278 template <typename ExecutionContext>
279 basic_socket_acceptor(ExecutionContext& context,
280 const endpoint_type& endpoint, bool reuse_addr = true,
281 typename constraint<
282 is_convertible<ExecutionContext&, execution_context&>::value
283 >::type = 0)
284 : impl_(0, 0, context)
285 {
286 boost::system::error_code ec;
287 const protocol_type protocol = endpoint.protocol();
288 impl_.get_service().open(impl_.get_implementation(), protocol, ec);
289 boost::asio::detail::throw_error(ec, "open");
290 if (reuse_addr)
291 {
292 impl_.get_service().set_option(impl_.get_implementation(),
293 socket_base::reuse_address(true), ec);
294 boost::asio::detail::throw_error(ec, "set_option");
295 }
296 impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
297 boost::asio::detail::throw_error(ec, "bind");
298 impl_.get_service().listen(impl_.get_implementation(),
299 socket_base::max_listen_connections, ec);
300 boost::asio::detail::throw_error(ec, "listen");
301 }
302
303 /// Construct a basic_socket_acceptor on an existing native acceptor.
304 /**
305 * This constructor creates an acceptor object to hold an existing native
306 * acceptor.
307 *
308 * @param ex The I/O executor that the acceptor will use, by default, to
309 * dispatch handlers for any asynchronous operations performed on the
310 * acceptor.
311 *
312 * @param protocol An object specifying protocol parameters to be used.
313 *
314 * @param native_acceptor A native acceptor.
315 *
316 * @throws boost::system::system_error Thrown on failure.
317 */
318 basic_socket_acceptor(const executor_type& ex,
319 const protocol_type& protocol, const native_handle_type& native_acceptor)
320 : impl_(0, ex)
321 {
322 boost::system::error_code ec;
323 impl_.get_service().assign(impl_.get_implementation(),
324 protocol, native_acceptor, ec);
325 boost::asio::detail::throw_error(ec, "assign");
326 }
327
328 /// Construct a basic_socket_acceptor on an existing native acceptor.
329 /**
330 * This constructor creates an acceptor object to hold an existing native
331 * acceptor.
332 *
333 * @param context An execution context which provides the I/O executor that
334 * the acceptor will use, by default, to dispatch handlers for any
335 * asynchronous operations performed on the acceptor.
336 *
337 * @param protocol An object specifying protocol parameters to be used.
338 *
339 * @param native_acceptor A native acceptor.
340 *
341 * @throws boost::system::system_error Thrown on failure.
342 */
343 template <typename ExecutionContext>
344 basic_socket_acceptor(ExecutionContext& context,
345 const protocol_type& protocol, const native_handle_type& native_acceptor,
346 typename constraint<
347 is_convertible<ExecutionContext&, execution_context&>::value
348 >::type = 0)
349 : impl_(0, 0, context)
350 {
351 boost::system::error_code ec;
352 impl_.get_service().assign(impl_.get_implementation(),
353 protocol, native_acceptor, ec);
354 boost::asio::detail::throw_error(ec, "assign");
355 }
356
357 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
358 /// Move-construct a basic_socket_acceptor from another.
359 /**
360 * This constructor moves an acceptor from one object to another.
361 *
362 * @param other The other basic_socket_acceptor object from which the move
363 * will occur.
364 *
365 * @note Following the move, the moved-from object is in the same state as if
366 * constructed using the @c basic_socket_acceptor(const executor_type&)
367 * constructor.
368 */
369 basic_socket_acceptor(basic_socket_acceptor&& other) BOOST_ASIO_NOEXCEPT
370 : impl_(std::move(other.impl_))
371 {
372 }
373
374 /// Move-assign a basic_socket_acceptor from another.
375 /**
376 * This assignment operator moves an acceptor from one object to another.
377 *
378 * @param other The other basic_socket_acceptor object from which the move
379 * will occur.
380 *
381 * @note Following the move, the moved-from object is in the same state as if
382 * constructed using the @c basic_socket_acceptor(const executor_type&)
383 * constructor.
384 */
385 basic_socket_acceptor& operator=(basic_socket_acceptor&& other)
386 {
387 impl_ = std::move(other.impl_);
388 return *this;
389 }
390
391 // All socket acceptors have access to each other's implementations.
392 template <typename Protocol1, typename Executor1>
393 friend class basic_socket_acceptor;
394
395 /// Move-construct a basic_socket_acceptor from an acceptor of another
396 /// protocol type.
397 /**
398 * This constructor moves an acceptor from one object to another.
399 *
400 * @param other The other basic_socket_acceptor object from which the move
401 * will occur.
402 *
403 * @note Following the move, the moved-from object is in the same state as if
404 * constructed using the @c basic_socket_acceptor(const executor_type&)
405 * constructor.
406 */
407 template <typename Protocol1, typename Executor1>
408 basic_socket_acceptor(basic_socket_acceptor<Protocol1, Executor1>&& other,
409 typename constraint<
410 is_convertible<Protocol1, Protocol>::value
411 && is_convertible<Executor1, Executor>::value
412 >::type = 0)
413 : impl_(std::move(other.impl_))
414 {
415 }
416
417 /// Move-assign a basic_socket_acceptor from an acceptor of another protocol
418 /// type.
419 /**
420 * This assignment operator moves an acceptor from one object to another.
421 *
422 * @param other The other basic_socket_acceptor object from which the move
423 * will occur.
424 *
425 * @note Following the move, the moved-from object is in the same state as if
426 * constructed using the @c basic_socket_acceptor(const executor_type&)
427 * constructor.
428 */
429 template <typename Protocol1, typename Executor1>
430 typename constraint<
431 is_convertible<Protocol1, Protocol>::value
432 && is_convertible<Executor1, Executor>::value,
433 basic_socket_acceptor&
434 >::type operator=(basic_socket_acceptor<Protocol1, Executor1>&& other)
435 {
436 basic_socket_acceptor tmp(std::move(other));
437 impl_ = std::move(tmp.impl_);
438 return *this;
439 }
440 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
441
442 /// Destroys the acceptor.
443 /**
444 * This function destroys the acceptor, cancelling any outstanding
445 * asynchronous operations associated with the acceptor as if by calling
446 * @c cancel.
447 */
448 ~basic_socket_acceptor()
449 {
450 }
451
452 /// Get the executor associated with the object.
453 executor_type get_executor() BOOST_ASIO_NOEXCEPT
454 {
455 return impl_.get_executor();
456 }
457
458 /// Open the acceptor using the specified protocol.
459 /**
460 * This function opens the socket acceptor so that it will use the specified
461 * protocol.
462 *
463 * @param protocol An object specifying which protocol is to be used.
464 *
465 * @throws boost::system::system_error Thrown on failure.
466 *
467 * @par Example
468 * @code
469 * boost::asio::ip::tcp::acceptor acceptor(my_context);
470 * acceptor.open(boost::asio::ip::tcp::v4());
471 * @endcode
472 */
473 void open(const protocol_type& protocol = protocol_type())
474 {
475 boost::system::error_code ec;
476 impl_.get_service().open(impl_.get_implementation(), protocol, ec);
477 boost::asio::detail::throw_error(ec, "open");
478 }
479
480 /// Open the acceptor using the specified protocol.
481 /**
482 * This function opens the socket acceptor so that it will use the specified
483 * protocol.
484 *
485 * @param protocol An object specifying which protocol is to be used.
486 *
487 * @param ec Set to indicate what error occurred, if any.
488 *
489 * @par Example
490 * @code
491 * boost::asio::ip::tcp::acceptor acceptor(my_context);
492 * boost::system::error_code ec;
493 * acceptor.open(boost::asio::ip::tcp::v4(), ec);
494 * if (ec)
495 * {
496 * // An error occurred.
497 * }
498 * @endcode
499 */
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(ec, "assign");
524 }
525
526 /// Assigns an existing native acceptor to the acceptor.
527 /*
528 * This function opens the acceptor to hold an existing native acceptor.
529 *
530 * @param protocol An object specifying which protocol is to be used.
531 *
532 * @param native_acceptor A native acceptor.
533 *
534 * @param ec Set to indicate what error occurred, if any.
535 */
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(ec, "bind");
573 }
574
575 /// Bind the acceptor to the given local endpoint.
576 /**
577 * This function binds the socket acceptor to the specified endpoint on the
578 * local machine.
579 *
580 * @param endpoint An endpoint on the local machine to which the socket
581 * acceptor will be bound.
582 *
583 * @param ec Set to indicate what error occurred, if any.
584 *
585 * @par Example
586 * @code
587 * boost::asio::ip::tcp::acceptor acceptor(my_context);
588 * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345);
589 * acceptor.open(endpoint.protocol());
590 * boost::system::error_code ec;
591 * acceptor.bind(endpoint, ec);
592 * if (ec)
593 * {
594 * // An error occurred.
595 * }
596 * @endcode
597 */
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(ec, "listen");
620 }
621
622 /// Place the acceptor into the state where it will listen for new
623 /// connections.
624 /**
625 * This function puts the socket acceptor into the state where it may accept
626 * new connections.
627 *
628 * @param backlog The maximum length of the queue of pending connections.
629 *
630 * @param ec Set to indicate what error occurred, if any.
631 *
632 * @par Example
633 * @code
634 * boost::asio::ip::tcp::acceptor acceptor(my_context);
635 * ...
636 * boost::system::error_code ec;
637 * acceptor.listen(boost::asio::socket_base::max_listen_connections, ec);
638 * if (ec)
639 * {
640 * // An error occurred.
641 * }
642 * @endcode
643 */
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(ec, "close");
665 }
666
667 /// Close the acceptor.
668 /**
669 * This function is used to close the acceptor. Any asynchronous accept
670 * operations will be cancelled immediately.
671 *
672 * A subsequent call to open() is required before the acceptor can again be
673 * used to again perform socket accept operations.
674 *
675 * @param ec Set to indicate what error occurred, if any.
676 *
677 * @par Example
678 * @code
679 * boost::asio::ip::tcp::acceptor acceptor(my_context);
680 * ...
681 * boost::system::error_code ec;
682 * acceptor.close(ec);
683 * if (ec)
684 * {
685 * // An error occurred.
686 * }
687 * @endcode
688 */
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(ec, "release");
720 return s;
721 }
722
723 /// Release ownership of the underlying native acceptor.
724 /**
725 * This function causes all outstanding asynchronous accept operations to
726 * finish immediately, and the handlers for cancelled operations will be
727 * passed the boost::asio::error::operation_aborted error. Ownership of the
728 * native acceptor is then transferred to the caller.
729 *
730 * @param ec Set to indicate what error occurred, if any.
731 *
732 * @note This function is unsupported on Windows versions prior to Windows
733 * 8.1, and will fail with boost::asio::error::operation_not_supported on
734 * these platforms.
735 */
736 #if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
737 && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
738 __declspec(deprecated("This function always fails with "
739 "operation_not_supported when used on Windows versions "
740 "prior to Windows 8.1."))
741 #endif
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(ec, "cancel");
771 }
772
773 /// Cancel all asynchronous operations associated with the acceptor.
774 /**
775 * This function causes all outstanding asynchronous connect, send and receive
776 * operations to finish immediately, and the handlers for cancelled operations
777 * will be passed the boost::asio::error::operation_aborted error.
778 *
779 * @param ec Set to indicate what error occurred, if any.
780 */
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(ec, "set_option");
814 }
815
816 /// Set an option on the acceptor.
817 /**
818 * This function is used to set an option on the acceptor.
819 *
820 * @param option The new option value to be set on the acceptor.
821 *
822 * @param ec Set to indicate what error occurred, if any.
823 *
824 * @sa SettableSocketOption @n
825 * boost::asio::socket_base::reuse_address
826 * boost::asio::socket_base::enable_connection_aborted
827 *
828 * @par Example
829 * Setting the SOL_SOCKET/SO_REUSEADDR option:
830 * @code
831 * boost::asio::ip::tcp::acceptor acceptor(my_context);
832 * ...
833 * boost::asio::ip::tcp::acceptor::reuse_address option(true);
834 * boost::system::error_code ec;
835 * acceptor.set_option(option, ec);
836 * if (ec)
837 * {
838 * // An error occurred.
839 * }
840 * @endcode
841 */
842 template <typename SettableSocketOption>
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(ec, "get_option");
878 }
879
880 /// Get an option from the acceptor.
881 /**
882 * This function is used to get the current value of an option on the
883 * acceptor.
884 *
885 * @param option The option value to be obtained from the acceptor.
886 *
887 * @param ec Set to indicate what error occurred, if any.
888 *
889 * @sa GettableSocketOption @n
890 * boost::asio::socket_base::reuse_address
891 *
892 * @par Example
893 * Getting the value of the SOL_SOCKET/SO_REUSEADDR option:
894 * @code
895 * boost::asio::ip::tcp::acceptor acceptor(my_context);
896 * ...
897 * boost::asio::ip::tcp::acceptor::reuse_address option;
898 * boost::system::error_code ec;
899 * acceptor.get_option(option, ec);
900 * if (ec)
901 * {
902 * // An error occurred.
903 * }
904 * bool is_set = option.get();
905 * @endcode
906 */
907 template <typename GettableSocketOption>
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(ec, "io_control");
941 }
942
943 /// Perform an IO control command on the acceptor.
944 /**
945 * This function is used to execute an IO control command on the acceptor.
946 *
947 * @param command The IO control command to be performed on the acceptor.
948 *
949 * @param ec Set to indicate what error occurred, if any.
950 *
951 * @sa IoControlCommand @n
952 * boost::asio::socket_base::non_blocking_io
953 *
954 * @par Example
955 * Getting the number of bytes ready to read:
956 * @code
957 * boost::asio::ip::tcp::acceptor acceptor(my_context);
958 * ...
959 * boost::asio::ip::tcp::acceptor::non_blocking_io command(true);
960 * boost::system::error_code ec;
961 * socket.io_control(command, ec);
962 * if (ec)
963 * {
964 * // An error occurred.
965 * }
966 * @endcode
967 */
968 template <typename IoControlCommand>
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(ec, "non_blocking");
1010 }
1011
1012 /// Sets the non-blocking mode of the acceptor.
1013 /**
1014 * @param mode If @c true, the acceptor's synchronous operations will fail
1015 * with boost::asio::error::would_block if they are unable to perform the
1016 * requested operation immediately. If @c false, synchronous operations will
1017 * block until complete.
1018 *
1019 * @param ec Set to indicate what error occurred, if any.
1020 *
1021 * @note The non-blocking mode has no effect on the behaviour of asynchronous
1022 * operations. Asynchronous operations will never fail with the error
1023 * boost::asio::error::would_block.
1024 */
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(ec, "native_non_blocking");
1072 }
1073
1074 /// Sets the non-blocking mode of the native acceptor implementation.
1075 /**
1076 * This function is used to modify the non-blocking mode of the underlying
1077 * native acceptor. It has no effect on the behaviour of the acceptor object's
1078 * synchronous operations.
1079 *
1080 * @param mode If @c true, the underlying acceptor is put into non-blocking
1081 * mode and direct system calls may fail with boost::asio::error::would_block
1082 * (or the equivalent system error).
1083 *
1084 * @param ec Set to indicate what error occurred, if any. If the @c mode is
1085 * @c false, but the current value of @c non_blocking() is @c true, this
1086 * function fails with boost::asio::error::invalid_argument, as the
1087 * combination does not make sense.
1088 */
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(ec, "local_endpoint");
1118 return ep;
1119 }
1120
1121 /// Get the local endpoint of the acceptor.
1122 /**
1123 * This function is used to obtain the locally bound endpoint of the acceptor.
1124 *
1125 * @param ec Set to indicate what error occurred, if any.
1126 *
1127 * @returns An object that represents the local endpoint of the acceptor.
1128 * Returns a default-constructed endpoint object if an error occurred and the
1129 * error handler did not throw an exception.
1130 *
1131 * @par Example
1132 * @code
1133 * boost::asio::ip::tcp::acceptor acceptor(my_context);
1134 * ...
1135 * boost::system::error_code ec;
1136 * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec);
1137 * if (ec)
1138 * {
1139 * // An error occurred.
1140 * }
1141 * @endcode
1142 */
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(ec, "wait");
1169 }
1170
1171 /// Wait for the acceptor to become ready to read, ready to write, or to have
1172 /// pending error conditions.
1173 /**
1174 * This function is used to perform a blocking wait for an acceptor to enter
1175 * a ready to read, write or error condition state.
1176 *
1177 * @param w Specifies the desired acceptor state.
1178 *
1179 * @param ec Set to indicate what error occurred, if any.
1180 *
1181 * @par Example
1182 * Waiting for an acceptor to become readable.
1183 * @code
1184 * boost::asio::ip::tcp::acceptor acceptor(my_context);
1185 * ...
1186 * boost::system::error_code ec;
1187 * acceptor.wait(boost::asio::ip::tcp::acceptor::wait_read, ec);
1188 * @endcode
1189 */
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 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
1254 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WaitToken,
1255 void (boost::system::error_code))
1256 async_wait(wait_type w,
1257 BOOST_ASIO_MOVE_ARG(WaitToken) token
1258 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
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 typename constraint<
1286 is_convertible<Protocol, Protocol1>::value
1287 >::type = 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(ec, "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 typename constraint<
1322 is_convertible<Protocol, Protocol1>::value
1323 >::type = 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 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
1388 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(AcceptToken,
1389 void (boost::system::error_code))
1390 async_accept(basic_socket<Protocol1, Executor1>& peer,
1391 BOOST_ASIO_MOVE_ARG(AcceptToken) token
1392 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
1393 typename constraint<
1394 is_convertible<Protocol, Protocol1>::value
1395 >::type = 0)
1396 {
1397 return async_initiate<AcceptToken, void (boost::system::error_code)>(
1398 initiate_async_accept(this), token,
1399 &peer, static_cast<endpoint_type*>(0));
1400 }
1401
1402 /// Accept a new connection and obtain the endpoint of the peer
1403 /**
1404 * This function is used to accept a new connection from a peer into the
1405 * given socket, and additionally provide the endpoint of the remote peer.
1406 * The function call will block until a new connection has been accepted
1407 * successfully or an error occurs.
1408 *
1409 * @param peer The socket into which the new connection will be accepted.
1410 *
1411 * @param peer_endpoint An endpoint object which will receive the endpoint of
1412 * the remote peer.
1413 *
1414 * @throws boost::system::system_error Thrown on failure.
1415 *
1416 * @par Example
1417 * @code
1418 * boost::asio::ip::tcp::acceptor acceptor(my_context);
1419 * ...
1420 * boost::asio::ip::tcp::socket socket(my_context);
1421 * boost::asio::ip::tcp::endpoint endpoint;
1422 * acceptor.accept(socket, endpoint);
1423 * @endcode
1424 */
1425 template <typename Executor1>
1426 void accept(basic_socket<protocol_type, Executor1>& peer,
1427 endpoint_type& peer_endpoint)
1428 {
1429 boost::system::error_code ec;
1430 impl_.get_service().accept(impl_.get_implementation(),
1431 peer, &peer_endpoint, ec);
1432 boost::asio::detail::throw_error(ec, "accept");
1433 }
1434
1435 /// Accept a new connection and obtain the endpoint of the peer
1436 /**
1437 * This function is used to accept a new connection from a peer into the
1438 * given socket, and additionally provide the endpoint of the remote peer.
1439 * The function call will block until a new connection has been accepted
1440 * successfully or an error occurs.
1441 *
1442 * @param peer The socket into which the new connection will be accepted.
1443 *
1444 * @param peer_endpoint An endpoint object which will receive the endpoint of
1445 * the remote peer.
1446 *
1447 * @param ec Set to indicate what error occurred, if any.
1448 *
1449 * @par Example
1450 * @code
1451 * boost::asio::ip::tcp::acceptor acceptor(my_context);
1452 * ...
1453 * boost::asio::ip::tcp::socket socket(my_context);
1454 * boost::asio::ip::tcp::endpoint endpoint;
1455 * boost::system::error_code ec;
1456 * acceptor.accept(socket, endpoint, ec);
1457 * if (ec)
1458 * {
1459 * // An error occurred.
1460 * }
1461 * @endcode
1462 */
1463 template <typename Executor1>
1464 BOOST_ASIO_SYNC_OP_VOID accept(basic_socket<protocol_type, Executor1>& peer,
1465 endpoint_type& peer_endpoint, boost::system::error_code& ec)
1466 {
1467 impl_.get_service().accept(
1468 impl_.get_implementation(), peer, &peer_endpoint, ec);
1469 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
1470 }
1471
1472 /// Start an asynchronous accept.
1473 /**
1474 * This function is used to asynchronously accept a new connection into a
1475 * socket, and additionally obtain the endpoint of the remote peer. It is an
1476 * initiating function for an @ref asynchronous_operation, and always returns
1477 * immediately.
1478 *
1479 * @param peer The socket into which the new connection will be accepted.
1480 * Ownership of the peer object is retained by the caller, which must
1481 * guarantee that it is valid until the completion handler is called.
1482 *
1483 * @param peer_endpoint An endpoint object into which the endpoint of the
1484 * remote peer will be written. Ownership of the peer_endpoint object is
1485 * retained by the caller, which must guarantee that it is valid until the
1486 * handler is called.
1487 *
1488 * @param token The @ref completion_token that will be used to produce a
1489 * completion handler, which will be called when the accept completes.
1490 * Potential completion tokens include @ref use_future, @ref use_awaitable,
1491 * @ref yield_context, or a function object with the correct completion
1492 * signature. The function signature of the completion handler must be:
1493 * @code void handler(
1494 * const boost::system::error_code& error // Result of operation.
1495 * ); @endcode
1496 * Regardless of whether the asynchronous operation completes immediately or
1497 * not, the completion handler will not be invoked from within this function.
1498 * On immediate completion, invocation of the handler will be performed in a
1499 * manner equivalent to using boost::asio::post().
1500 *
1501 * @par Completion Signature
1502 * @code void(boost::system::error_code) @endcode
1503 *
1504 * @par Per-Operation Cancellation
1505 * On POSIX or Windows operating systems, this asynchronous operation supports
1506 * cancellation for the following boost::asio::cancellation_type values:
1507 *
1508 * @li @c cancellation_type::terminal
1509 *
1510 * @li @c cancellation_type::partial
1511 *
1512 * @li @c cancellation_type::total
1513 */
1514 template <typename Executor1,
1515 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
1516 AcceptToken BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
1517 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(AcceptToken,
1518 void (boost::system::error_code))
1519 async_accept(basic_socket<protocol_type, Executor1>& peer,
1520 endpoint_type& peer_endpoint,
1521 BOOST_ASIO_MOVE_ARG(AcceptToken) token
1522 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
1523 {
1524 return async_initiate<AcceptToken, void (boost::system::error_code)>(
1525 initiate_async_accept(this), token, &peer, &peer_endpoint);
1526 }
1527 #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
1528
1529 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
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(ec, "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 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
1660 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptToken,
1661 void (boost::system::error_code,
1662 typename Protocol::socket::template
1663 rebind_executor<executor_type>::other))
1664 async_accept(
1665 BOOST_ASIO_MOVE_ARG(MoveAcceptToken) token
1666 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
1667 {
1668 return async_initiate<MoveAcceptToken,
1669 void (boost::system::error_code, typename Protocol::socket::template
1670 rebind_executor<executor_type>::other)>(
1671 initiate_async_move_accept(this), token,
1672 impl_.get_executor(), static_cast<endpoint_type*>(0),
1673 static_cast<typename Protocol::socket::template
1674 rebind_executor<executor_type>::other*>(0));
1675 }
1676
1677 /// Accept a new connection.
1678 /**
1679 * This function is used to accept a new connection from a peer. The function
1680 * call will block until a new connection has been accepted successfully or
1681 * an error occurs.
1682 *
1683 * This overload requires that the Protocol template parameter satisfy the
1684 * AcceptableProtocol type requirements.
1685 *
1686 * @param ex The I/O executor object to be used for the newly
1687 * accepted socket.
1688 *
1689 * @returns A socket object representing the newly accepted connection.
1690 *
1691 * @throws boost::system::system_error Thrown on failure.
1692 *
1693 * @par Example
1694 * @code
1695 * boost::asio::ip::tcp::acceptor acceptor(my_context);
1696 * ...
1697 * boost::asio::ip::tcp::socket socket(acceptor.accept());
1698 * @endcode
1699 */
1700 template <typename Executor1>
1701 typename Protocol::socket::template rebind_executor<Executor1>::other
1702 accept(const Executor1& ex,
1703 typename constraint<
1704 is_executor<Executor1>::value
1705 || execution::is_executor<Executor1>::value
1706 >::type = 0)
1707 {
1708 boost::system::error_code ec;
1709 typename Protocol::socket::template
1710 rebind_executor<Executor1>::other peer(ex);
1711 impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
1712 boost::asio::detail::throw_error(ec, "accept");
1713 return peer;
1714 }
1715
1716 /// Accept a new connection.
1717 /**
1718 * This function is used to accept a new connection from a peer. The function
1719 * call will block until a new connection has been accepted successfully or
1720 * an error occurs.
1721 *
1722 * This overload requires that the Protocol template parameter satisfy the
1723 * AcceptableProtocol type requirements.
1724 *
1725 * @param context The I/O execution context object to be used for the newly
1726 * accepted socket.
1727 *
1728 * @returns A socket object representing the newly accepted connection.
1729 *
1730 * @throws boost::system::system_error Thrown on failure.
1731 *
1732 * @par Example
1733 * @code
1734 * boost::asio::ip::tcp::acceptor acceptor(my_context);
1735 * ...
1736 * boost::asio::ip::tcp::socket socket(acceptor.accept());
1737 * @endcode
1738 */
1739 template <typename ExecutionContext>
1740 typename Protocol::socket::template rebind_executor<
1741 typename ExecutionContext::executor_type>::other
1742 accept(ExecutionContext& context,
1743 typename constraint<
1744 is_convertible<ExecutionContext&, execution_context&>::value
1745 >::type = 0)
1746 {
1747 boost::system::error_code ec;
1748 typename Protocol::socket::template rebind_executor<
1749 typename ExecutionContext::executor_type>::other peer(context);
1750 impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
1751 boost::asio::detail::throw_error(ec, "accept");
1752 return peer;
1753 }
1754
1755 /// Accept a new connection.
1756 /**
1757 * This function is used to accept a new connection from a peer. The function
1758 * call will block until a new connection has been accepted successfully or
1759 * an error occurs.
1760 *
1761 * This overload requires that the Protocol template parameter satisfy the
1762 * AcceptableProtocol type requirements.
1763 *
1764 * @param ex The I/O executor object to be used for the newly accepted
1765 * socket.
1766 *
1767 * @param ec Set to indicate what error occurred, if any.
1768 *
1769 * @returns On success, a socket object representing the newly accepted
1770 * connection. On error, a socket object where is_open() is false.
1771 *
1772 * @par Example
1773 * @code
1774 * boost::asio::ip::tcp::acceptor acceptor(my_context);
1775 * ...
1776 * boost::asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec));
1777 * if (ec)
1778 * {
1779 * // An error occurred.
1780 * }
1781 * @endcode
1782 */
1783 template <typename Executor1>
1784 typename Protocol::socket::template rebind_executor<Executor1>::other
1785 accept(const Executor1& ex, boost::system::error_code& ec,
1786 typename constraint<
1787 is_executor<Executor1>::value
1788 || execution::is_executor<Executor1>::value
1789 >::type = 0)
1790 {
1791 typename Protocol::socket::template
1792 rebind_executor<Executor1>::other peer(ex);
1793 impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
1794 return peer;
1795 }
1796
1797 /// Accept a new connection.
1798 /**
1799 * This function is used to accept a new connection from a peer. The function
1800 * call will block until a new connection has been accepted successfully or
1801 * an error occurs.
1802 *
1803 * This overload requires that the Protocol template parameter satisfy the
1804 * AcceptableProtocol type requirements.
1805 *
1806 * @param context The I/O execution context object to be used for the newly
1807 * accepted socket.
1808 *
1809 * @param ec Set to indicate what error occurred, if any.
1810 *
1811 * @returns On success, a socket object representing the newly accepted
1812 * connection. On error, a socket object where is_open() is false.
1813 *
1814 * @par Example
1815 * @code
1816 * boost::asio::ip::tcp::acceptor acceptor(my_context);
1817 * ...
1818 * boost::asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec));
1819 * if (ec)
1820 * {
1821 * // An error occurred.
1822 * }
1823 * @endcode
1824 */
1825 template <typename ExecutionContext>
1826 typename Protocol::socket::template rebind_executor<
1827 typename ExecutionContext::executor_type>::other
1828 accept(ExecutionContext& context, boost::system::error_code& ec,
1829 typename constraint<
1830 is_convertible<ExecutionContext&, execution_context&>::value
1831 >::type = 0)
1832 {
1833 typename Protocol::socket::template rebind_executor<
1834 typename ExecutionContext::executor_type>::other peer(context);
1835 impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
1836 return peer;
1837 }
1838
1839 /// Start an asynchronous accept.
1840 /**
1841 * This function is used to asynchronously accept a new connection. It is an
1842 * initiating function for an @ref asynchronous_operation, and always returns
1843 * immediately.
1844 *
1845 * This overload requires that the Protocol template parameter satisfy the
1846 * AcceptableProtocol type requirements.
1847 *
1848 * @param ex The I/O executor object to be used for the newly accepted
1849 * socket.
1850 *
1851 * @param token The @ref completion_token that will be used to produce a
1852 * completion handler, which will be called when the accept completes.
1853 * Potential completion tokens include @ref use_future, @ref use_awaitable,
1854 * @ref yield_context, or a function object with the correct completion
1855 * signature. The function signature of the completion handler must be:
1856 * @code void handler(
1857 * // Result of operation.
1858 * const boost::system::error_code& error,
1859 *
1860 * // On success, the newly accepted socket.
1861 * typename Protocol::socket::template rebind_executor<
1862 * Executor1>::other peer
1863 * ); @endcode
1864 * Regardless of whether the asynchronous operation completes immediately or
1865 * not, the completion handler will not be invoked from within this function.
1866 * On immediate completion, invocation of the handler will be performed in a
1867 * manner equivalent to using boost::asio::post().
1868 *
1869 * @par Completion Signature
1870 * @code void(boost::system::error_code,
1871 * typename Protocol::socket::template rebind_executor<
1872 * Executor1>::other)) @endcode
1873 *
1874 * @par Example
1875 * @code
1876 * void accept_handler(const boost::system::error_code& error,
1877 * boost::asio::ip::tcp::socket peer)
1878 * {
1879 * if (!error)
1880 * {
1881 * // Accept succeeded.
1882 * }
1883 * }
1884 *
1885 * ...
1886 *
1887 * boost::asio::ip::tcp::acceptor acceptor(my_context);
1888 * ...
1889 * acceptor.async_accept(my_context2, accept_handler);
1890 * @endcode
1891 *
1892 * @par Per-Operation Cancellation
1893 * On POSIX or Windows operating systems, this asynchronous operation supports
1894 * cancellation for the following boost::asio::cancellation_type values:
1895 *
1896 * @li @c cancellation_type::terminal
1897 *
1898 * @li @c cancellation_type::partial
1899 *
1900 * @li @c cancellation_type::total
1901 */
1902 template <typename Executor1,
1903 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
1904 typename Protocol::socket::template rebind_executor<
1905 Executor1>::other)) MoveAcceptToken
1906 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
1907 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptToken,
1908 void (boost::system::error_code,
1909 typename Protocol::socket::template rebind_executor<
1910 Executor1>::other))
1911 async_accept(const Executor1& ex,
1912 BOOST_ASIO_MOVE_ARG(MoveAcceptToken) token
1913 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
1914 typename constraint<
1915 is_executor<Executor1>::value
1916 || execution::is_executor<Executor1>::value
1917 >::type = 0)
1918 {
1919 typedef typename Protocol::socket::template rebind_executor<
1920 Executor1>::other other_socket_type;
1921
1922 return async_initiate<MoveAcceptToken,
1923 void (boost::system::error_code, other_socket_type)>(
1924 initiate_async_move_accept(this), token,
1925 ex, static_cast<endpoint_type*>(0),
1926 static_cast<other_socket_type*>(0));
1927 }
1928
1929 /// Start an asynchronous accept.
1930 /**
1931 * This function is used to asynchronously accept a new connection. It is an
1932 * initiating function for an @ref asynchronous_operation, and always returns
1933 * immediately.
1934 *
1935 * This overload requires that the Protocol template parameter satisfy the
1936 * AcceptableProtocol type requirements.
1937 *
1938 * @param context The I/O execution context object to be used for the newly
1939 * accepted socket.
1940 *
1941 * @param token The @ref completion_token that will be used to produce a
1942 * completion handler, which will be called when the accept completes.
1943 * Potential completion tokens include @ref use_future, @ref use_awaitable,
1944 * @ref yield_context, or a function object with the correct completion
1945 * signature. The function signature of the completion handler must be:
1946 * @code void handler(
1947 * // Result of operation.
1948 * const boost::system::error_code& error,
1949 *
1950 * // On success, the newly accepted socket.
1951 * typename Protocol::socket::template rebind_executor<
1952 * typename ExecutionContext::executor_type>::other peer
1953 * ); @endcode
1954 * Regardless of whether the asynchronous operation completes immediately or
1955 * not, the completion handler will not be invoked from within this function.
1956 * On immediate completion, invocation of the handler will be performed in a
1957 * manner equivalent to using boost::asio::post().
1958 *
1959 * @par Completion Signature
1960 * @code void(boost::system::error_code,
1961 * typename Protocol::socket::template rebind_executor<
1962 * typename ExecutionContext::executor_type>::other)) @endcode
1963 *
1964 * @par Example
1965 * @code
1966 * void accept_handler(const boost::system::error_code& error,
1967 * boost::asio::ip::tcp::socket peer)
1968 * {
1969 * if (!error)
1970 * {
1971 * // Accept succeeded.
1972 * }
1973 * }
1974 *
1975 * ...
1976 *
1977 * boost::asio::ip::tcp::acceptor acceptor(my_context);
1978 * ...
1979 * acceptor.async_accept(my_context2, accept_handler);
1980 * @endcode
1981 *
1982 * @par Per-Operation Cancellation
1983 * On POSIX or Windows operating systems, this asynchronous operation supports
1984 * cancellation for the following boost::asio::cancellation_type values:
1985 *
1986 * @li @c cancellation_type::terminal
1987 *
1988 * @li @c cancellation_type::partial
1989 *
1990 * @li @c cancellation_type::total
1991 */
1992 template <typename ExecutionContext,
1993 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
1994 typename Protocol::socket::template rebind_executor<
1995 typename ExecutionContext::executor_type>::other)) MoveAcceptToken
1996 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
1997 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptToken,
1998 void (boost::system::error_code,
1999 typename Protocol::socket::template rebind_executor<
2000 typename ExecutionContext::executor_type>::other))
2001 async_accept(ExecutionContext& context,
2002 BOOST_ASIO_MOVE_ARG(MoveAcceptToken) token
2003 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
2004 typename constraint<
2005 is_convertible<ExecutionContext&, execution_context&>::value
2006 >::type = 0)
2007 {
2008 typedef typename Protocol::socket::template rebind_executor<
2009 typename ExecutionContext::executor_type>::other other_socket_type;
2010
2011 return async_initiate<MoveAcceptToken,
2012 void (boost::system::error_code, other_socket_type)>(
2013 initiate_async_move_accept(this), token,
2014 context.get_executor(), static_cast<endpoint_type*>(0),
2015 static_cast<other_socket_type*>(0));
2016 }
2017
2018 /// Accept a new connection.
2019 /**
2020 * This function is used to accept a new connection from a peer. The function
2021 * call will block until a new connection has been accepted successfully or
2022 * an error occurs.
2023 *
2024 * This overload requires that the Protocol template parameter satisfy the
2025 * AcceptableProtocol type requirements.
2026 *
2027 * @param peer_endpoint An endpoint object into which the endpoint of the
2028 * remote peer will be written.
2029 *
2030 * @returns A socket object representing the newly accepted connection.
2031 *
2032 * @throws boost::system::system_error Thrown on failure.
2033 *
2034 * @par Example
2035 * @code
2036 * boost::asio::ip::tcp::acceptor acceptor(my_context);
2037 * ...
2038 * boost::asio::ip::tcp::endpoint endpoint;
2039 * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint));
2040 * @endcode
2041 */
2042 typename Protocol::socket::template rebind_executor<executor_type>::other
2043 accept(endpoint_type& peer_endpoint)
2044 {
2045 boost::system::error_code ec;
2046 typename Protocol::socket::template rebind_executor<
2047 executor_type>::other peer(impl_.get_executor());
2048 impl_.get_service().accept(impl_.get_implementation(),
2049 peer, &peer_endpoint, ec);
2050 boost::asio::detail::throw_error(ec, "accept");
2051 return peer;
2052 }
2053
2054 /// Accept a new connection.
2055 /**
2056 * This function is used to accept a new connection from a peer. The function
2057 * call will block until a new connection has been accepted successfully or
2058 * an error occurs.
2059 *
2060 * This overload requires that the Protocol template parameter satisfy the
2061 * AcceptableProtocol type requirements.
2062 *
2063 * @param peer_endpoint An endpoint object into which the endpoint of the
2064 * remote peer will be written.
2065 *
2066 * @param ec Set to indicate what error occurred, if any.
2067 *
2068 * @returns On success, a socket object representing the newly accepted
2069 * connection. On error, a socket object where is_open() is false.
2070 *
2071 * @par Example
2072 * @code
2073 * boost::asio::ip::tcp::acceptor acceptor(my_context);
2074 * ...
2075 * boost::asio::ip::tcp::endpoint endpoint;
2076 * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint, ec));
2077 * if (ec)
2078 * {
2079 * // An error occurred.
2080 * }
2081 * @endcode
2082 */
2083 typename Protocol::socket::template rebind_executor<executor_type>::other
2084 accept(endpoint_type& peer_endpoint, boost::system::error_code& ec)
2085 {
2086 typename Protocol::socket::template rebind_executor<
2087 executor_type>::other peer(impl_.get_executor());
2088 impl_.get_service().accept(impl_.get_implementation(),
2089 peer, &peer_endpoint, ec);
2090 return peer;
2091 }
2092
2093 /// Start an asynchronous accept.
2094 /**
2095 * This function is used to asynchronously accept a new connection. It is an
2096 * initiating function for an @ref asynchronous_operation, and always returns
2097 * immediately.
2098 *
2099 * This overload requires that the Protocol template parameter satisfy the
2100 * AcceptableProtocol type requirements.
2101 *
2102 * @param peer_endpoint An endpoint object into which the endpoint of the
2103 * remote peer will be written. Ownership of the peer_endpoint object is
2104 * retained by the caller, which must guarantee that it is valid until the
2105 * completion handler is called.
2106 *
2107 * @param token The @ref completion_token that will be used to produce a
2108 * completion handler, which will be called when the accept completes.
2109 * Potential completion tokens include @ref use_future, @ref use_awaitable,
2110 * @ref yield_context, or a function object with the correct completion
2111 * signature. The function signature of the completion handler must be:
2112 * @code void handler(
2113 * // Result of operation.
2114 * const boost::system::error_code& error,
2115 *
2116 * // On success, the newly accepted socket.
2117 * typename Protocol::socket::template
2118 * rebind_executor<executor_type>::other peer
2119 * ); @endcode
2120 * Regardless of whether the asynchronous operation completes immediately or
2121 * not, the completion handler will not be invoked from within this function.
2122 * On immediate completion, invocation of the handler will be performed in a
2123 * manner equivalent to using boost::asio::post().
2124 *
2125 * @par Completion Signature
2126 * @code void(boost::system::error_code,
2127 * typename Protocol::socket::template
2128 * rebind_executor<executor_type>::other)) @endcode
2129 *
2130 * @par Example
2131 * @code
2132 * void accept_handler(const boost::system::error_code& error,
2133 * boost::asio::ip::tcp::socket peer)
2134 * {
2135 * if (!error)
2136 * {
2137 * // Accept succeeded.
2138 * }
2139 * }
2140 *
2141 * ...
2142 *
2143 * boost::asio::ip::tcp::acceptor acceptor(my_context);
2144 * ...
2145 * boost::asio::ip::tcp::endpoint endpoint;
2146 * acceptor.async_accept(endpoint, accept_handler);
2147 * @endcode
2148 *
2149 * @par Per-Operation Cancellation
2150 * On POSIX or Windows operating systems, this asynchronous operation supports
2151 * cancellation for the following boost::asio::cancellation_type values:
2152 *
2153 * @li @c cancellation_type::terminal
2154 *
2155 * @li @c cancellation_type::partial
2156 *
2157 * @li @c cancellation_type::total
2158 */
2159 template <
2160 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
2161 typename Protocol::socket::template rebind_executor<
2162 executor_type>::other)) MoveAcceptToken
2163 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
2164 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptToken,
2165 void (boost::system::error_code,
2166 typename Protocol::socket::template
2167 rebind_executor<executor_type>::other))
2168 async_accept(endpoint_type& peer_endpoint,
2169 BOOST_ASIO_MOVE_ARG(MoveAcceptToken) token
2170 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
2171 {
2172 return async_initiate<MoveAcceptToken,
2173 void (boost::system::error_code, typename Protocol::socket::template
2174 rebind_executor<executor_type>::other)>(
2175 initiate_async_move_accept(this), token,
2176 impl_.get_executor(), &peer_endpoint,
2177 static_cast<typename Protocol::socket::template
2178 rebind_executor<executor_type>::other*>(0));
2179 }
2180
2181 /// Accept a new connection.
2182 /**
2183 * This function is used to accept a new connection from a peer. The function
2184 * call will block until a new connection has been accepted successfully or
2185 * an error occurs.
2186 *
2187 * This overload requires that the Protocol template parameter satisfy the
2188 * AcceptableProtocol type requirements.
2189 *
2190 * @param ex The I/O executor object to be used for the newly accepted
2191 * socket.
2192 *
2193 * @param peer_endpoint An endpoint object into which the endpoint of the
2194 * remote peer will be written.
2195 *
2196 * @returns A socket object representing the newly accepted connection.
2197 *
2198 * @throws boost::system::system_error Thrown on failure.
2199 *
2200 * @par Example
2201 * @code
2202 * boost::asio::ip::tcp::acceptor acceptor(my_context);
2203 * ...
2204 * boost::asio::ip::tcp::endpoint endpoint;
2205 * boost::asio::ip::tcp::socket socket(
2206 * acceptor.accept(my_context2, endpoint));
2207 * @endcode
2208 */
2209 template <typename Executor1>
2210 typename Protocol::socket::template rebind_executor<Executor1>::other
2211 accept(const Executor1& ex, endpoint_type& peer_endpoint,
2212 typename constraint<
2213 is_executor<Executor1>::value
2214 || execution::is_executor<Executor1>::value
2215 >::type = 0)
2216 {
2217 boost::system::error_code ec;
2218 typename Protocol::socket::template
2219 rebind_executor<Executor1>::other peer(ex);
2220 impl_.get_service().accept(impl_.get_implementation(),
2221 peer, &peer_endpoint, ec);
2222 boost::asio::detail::throw_error(ec, "accept");
2223 return peer;
2224 }
2225
2226 /// Accept a new connection.
2227 /**
2228 * This function is used to accept a new connection from a peer. The function
2229 * call will block until a new connection has been accepted successfully or
2230 * an error occurs.
2231 *
2232 * This overload requires that the Protocol template parameter satisfy the
2233 * AcceptableProtocol type requirements.
2234 *
2235 * @param context The I/O execution context object to be used for the newly
2236 * accepted socket.
2237 *
2238 * @param peer_endpoint An endpoint object into which the endpoint of the
2239 * remote peer will be written.
2240 *
2241 * @returns A socket object representing the newly accepted connection.
2242 *
2243 * @throws boost::system::system_error Thrown on failure.
2244 *
2245 * @par Example
2246 * @code
2247 * boost::asio::ip::tcp::acceptor acceptor(my_context);
2248 * ...
2249 * boost::asio::ip::tcp::endpoint endpoint;
2250 * boost::asio::ip::tcp::socket socket(
2251 * acceptor.accept(my_context2, endpoint));
2252 * @endcode
2253 */
2254 template <typename ExecutionContext>
2255 typename Protocol::socket::template rebind_executor<
2256 typename ExecutionContext::executor_type>::other
2257 accept(ExecutionContext& context, endpoint_type& peer_endpoint,
2258 typename constraint<
2259 is_convertible<ExecutionContext&, execution_context&>::value
2260 >::type = 0)
2261 {
2262 boost::system::error_code ec;
2263 typename Protocol::socket::template rebind_executor<
2264 typename ExecutionContext::executor_type>::other peer(context);
2265 impl_.get_service().accept(impl_.get_implementation(),
2266 peer, &peer_endpoint, ec);
2267 boost::asio::detail::throw_error(ec, "accept");
2268 return peer;
2269 }
2270
2271 /// Accept a new connection.
2272 /**
2273 * This function is used to accept a new connection from a peer. The function
2274 * call will block until a new connection has been accepted successfully or
2275 * an error occurs.
2276 *
2277 * This overload requires that the Protocol template parameter satisfy the
2278 * AcceptableProtocol type requirements.
2279 *
2280 * @param ex The I/O executor object to be used for the newly accepted
2281 * socket.
2282 *
2283 * @param peer_endpoint An endpoint object into which the endpoint of the
2284 * remote peer will be written.
2285 *
2286 * @param ec Set to indicate what error occurred, if any.
2287 *
2288 * @returns On success, a socket object representing the newly accepted
2289 * connection. On error, a socket object where is_open() is false.
2290 *
2291 * @par Example
2292 * @code
2293 * boost::asio::ip::tcp::acceptor acceptor(my_context);
2294 * ...
2295 * boost::asio::ip::tcp::endpoint endpoint;
2296 * boost::asio::ip::tcp::socket socket(
2297 * acceptor.accept(my_context2, endpoint, ec));
2298 * if (ec)
2299 * {
2300 * // An error occurred.
2301 * }
2302 * @endcode
2303 */
2304 template <typename Executor1>
2305 typename Protocol::socket::template rebind_executor<Executor1>::other
2306 accept(const executor_type& ex,
2307 endpoint_type& peer_endpoint, boost::system::error_code& ec,
2308 typename constraint<
2309 is_executor<Executor1>::value
2310 || execution::is_executor<Executor1>::value
2311 >::type = 0)
2312 {
2313 typename Protocol::socket::template
2314 rebind_executor<Executor1>::other peer(ex);
2315 impl_.get_service().accept(impl_.get_implementation(),
2316 peer, &peer_endpoint, ec);
2317 return peer;
2318 }
2319
2320 /// Accept a new connection.
2321 /**
2322 * This function is used to accept a new connection from a peer. The function
2323 * call will block until a new connection has been accepted successfully or
2324 * an error occurs.
2325 *
2326 * This overload requires that the Protocol template parameter satisfy the
2327 * AcceptableProtocol type requirements.
2328 *
2329 * @param context The I/O execution context object to be used for the newly
2330 * accepted socket.
2331 *
2332 * @param peer_endpoint An endpoint object into which the endpoint of the
2333 * remote peer will be written.
2334 *
2335 * @param ec Set to indicate what error occurred, if any.
2336 *
2337 * @returns On success, a socket object representing the newly accepted
2338 * connection. On error, a socket object where is_open() is false.
2339 *
2340 * @par Example
2341 * @code
2342 * boost::asio::ip::tcp::acceptor acceptor(my_context);
2343 * ...
2344 * boost::asio::ip::tcp::endpoint endpoint;
2345 * boost::asio::ip::tcp::socket socket(
2346 * acceptor.accept(my_context2, endpoint, ec));
2347 * if (ec)
2348 * {
2349 * // An error occurred.
2350 * }
2351 * @endcode
2352 */
2353 template <typename ExecutionContext>
2354 typename Protocol::socket::template rebind_executor<
2355 typename ExecutionContext::executor_type>::other
2356 accept(ExecutionContext& context,
2357 endpoint_type& peer_endpoint, boost::system::error_code& ec,
2358 typename constraint<
2359 is_convertible<ExecutionContext&, execution_context&>::value
2360 >::type = 0)
2361 {
2362 typename Protocol::socket::template rebind_executor<
2363 typename ExecutionContext::executor_type>::other peer(context);
2364 impl_.get_service().accept(impl_.get_implementation(),
2365 peer, &peer_endpoint, ec);
2366 return peer;
2367 }
2368
2369 /// Start an asynchronous accept.
2370 /**
2371 * This function is used to asynchronously accept a new connection. It is an
2372 * initiating function for an @ref asynchronous_operation, and always returns
2373 * immediately.
2374 *
2375 * This overload requires that the Protocol template parameter satisfy the
2376 * AcceptableProtocol type requirements.
2377 *
2378 * @param ex The I/O executor object to be used for the newly accepted
2379 * socket.
2380 *
2381 * @param peer_endpoint An endpoint object into which the endpoint of the
2382 * remote peer will be written. Ownership of the peer_endpoint object is
2383 * retained by the caller, which must guarantee that it is valid until the
2384 * completion handler is called.
2385 *
2386 * @param token The @ref completion_token that will be used to produce a
2387 * completion handler, which will be called when the accept completes.
2388 * Potential completion tokens include @ref use_future, @ref use_awaitable,
2389 * @ref yield_context, or a function object with the correct completion
2390 * signature. The function signature of the completion handler must be:
2391 * @code void handler(
2392 * // Result of operation.
2393 * const boost::system::error_code& error,
2394 *
2395 * // On success, the newly accepted socket.
2396 * typename Protocol::socket::template rebind_executor<
2397 * Executor1>::other peer
2398 * ); @endcode
2399 * Regardless of whether the asynchronous operation completes immediately or
2400 * not, the completion handler will not be invoked from within this function.
2401 * On immediate completion, invocation of the handler will be performed in a
2402 * manner equivalent to using boost::asio::post().
2403 *
2404 * @par Completion Signature
2405 * @code void(boost::system::error_code,
2406 * typename Protocol::socket::template rebind_executor<
2407 * Executor1>::other)) @endcode
2408 *
2409 * @par Example
2410 * @code
2411 * void accept_handler(const boost::system::error_code& error,
2412 * boost::asio::ip::tcp::socket peer)
2413 * {
2414 * if (!error)
2415 * {
2416 * // Accept succeeded.
2417 * }
2418 * }
2419 *
2420 * ...
2421 *
2422 * boost::asio::ip::tcp::acceptor acceptor(my_context);
2423 * ...
2424 * boost::asio::ip::tcp::endpoint endpoint;
2425 * acceptor.async_accept(my_context2, endpoint, accept_handler);
2426 * @endcode
2427 *
2428 * @par Per-Operation Cancellation
2429 * On POSIX or Windows operating systems, this asynchronous operation supports
2430 * cancellation for the following boost::asio::cancellation_type values:
2431 *
2432 * @li @c cancellation_type::terminal
2433 *
2434 * @li @c cancellation_type::partial
2435 *
2436 * @li @c cancellation_type::total
2437 */
2438 template <typename Executor1,
2439 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
2440 typename Protocol::socket::template rebind_executor<
2441 Executor1>::other)) MoveAcceptToken
2442 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
2443 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptToken,
2444 void (boost::system::error_code,
2445 typename Protocol::socket::template rebind_executor<
2446 Executor1>::other))
2447 async_accept(const Executor1& ex, endpoint_type& peer_endpoint,
2448 BOOST_ASIO_MOVE_ARG(MoveAcceptToken) token
2449 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
2450 typename constraint<
2451 is_executor<Executor1>::value
2452 || execution::is_executor<Executor1>::value
2453 >::type = 0)
2454 {
2455 typedef typename Protocol::socket::template rebind_executor<
2456 Executor1>::other other_socket_type;
2457
2458 return async_initiate<MoveAcceptToken,
2459 void (boost::system::error_code, other_socket_type)>(
2460 initiate_async_move_accept(this), token,
2461 ex, &peer_endpoint,
2462 static_cast<other_socket_type*>(0));
2463 }
2464
2465 /// Start an asynchronous accept.
2466 /**
2467 * This function is used to asynchronously accept a new connection. It is an
2468 * initiating function for an @ref asynchronous_operation, and always returns
2469 * immediately.
2470 *
2471 * This overload requires that the Protocol template parameter satisfy the
2472 * AcceptableProtocol type requirements.
2473 *
2474 * @param context The I/O execution context object to be used for the newly
2475 * accepted socket.
2476 *
2477 * @param peer_endpoint An endpoint object into which the endpoint of the
2478 * remote peer will be written. Ownership of the peer_endpoint object is
2479 * retained by the caller, which must guarantee that it is valid until the
2480 * completion handler is called.
2481 *
2482 * @param token The @ref completion_token that will be used to produce a
2483 * completion handler, which will be called when the accept completes.
2484 * Potential completion tokens include @ref use_future, @ref use_awaitable,
2485 * @ref yield_context, or a function object with the correct completion
2486 * signature. The function signature of the completion handler must be:
2487 * @code void handler(
2488 * // Result of operation.
2489 * const boost::system::error_code& error,
2490 *
2491 * // On success, the newly accepted socket.
2492 * typename Protocol::socket::template rebind_executor<
2493 * typename ExecutionContext::executor_type>::other peer
2494 * ); @endcode
2495 * Regardless of whether the asynchronous operation completes immediately or
2496 * not, the completion handler will not be invoked from within this function.
2497 * On immediate completion, invocation of the handler will be performed in a
2498 * manner equivalent to using boost::asio::post().
2499 *
2500 * @par Completion Signature
2501 * @code void(boost::system::error_code,
2502 * typename Protocol::socket::template rebind_executor<
2503 * typename ExecutionContext::executor_type>::other)) @endcode
2504 *
2505 * @par Example
2506 * @code
2507 * void accept_handler(const boost::system::error_code& error,
2508 * boost::asio::ip::tcp::socket peer)
2509 * {
2510 * if (!error)
2511 * {
2512 * // Accept succeeded.
2513 * }
2514 * }
2515 *
2516 * ...
2517 *
2518 * boost::asio::ip::tcp::acceptor acceptor(my_context);
2519 * ...
2520 * boost::asio::ip::tcp::endpoint endpoint;
2521 * acceptor.async_accept(my_context2, endpoint, accept_handler);
2522 * @endcode
2523 *
2524 * @par Per-Operation Cancellation
2525 * On POSIX or Windows operating systems, this asynchronous operation supports
2526 * cancellation for the following boost::asio::cancellation_type values:
2527 *
2528 * @li @c cancellation_type::terminal
2529 *
2530 * @li @c cancellation_type::partial
2531 *
2532 * @li @c cancellation_type::total
2533 */
2534 template <typename ExecutionContext,
2535 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
2536 typename Protocol::socket::template rebind_executor<
2537 typename ExecutionContext::executor_type>::other)) MoveAcceptToken
2538 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
2539 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptToken,
2540 void (boost::system::error_code,
2541 typename Protocol::socket::template rebind_executor<
2542 typename ExecutionContext::executor_type>::other))
2543 async_accept(ExecutionContext& context,
2544 endpoint_type& peer_endpoint,
2545 BOOST_ASIO_MOVE_ARG(MoveAcceptToken) token
2546 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
2547 typename constraint<
2548 is_convertible<ExecutionContext&, execution_context&>::value
2549 >::type = 0)
2550 {
2551 typedef typename Protocol::socket::template rebind_executor<
2552 typename ExecutionContext::executor_type>::other other_socket_type;
2553
2554 return async_initiate<MoveAcceptToken,
2555 void (boost::system::error_code, other_socket_type)>(
2556 initiate_async_move_accept(this), token,
2557 context.get_executor(), &peer_endpoint,
2558 static_cast<other_socket_type*>(0));
2559 }
2560 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
2561
2562 private:
2563 // Disallow copying and assignment.
2564 basic_socket_acceptor(const basic_socket_acceptor&) BOOST_ASIO_DELETED;
2565 basic_socket_acceptor& operator=(
2566 const basic_socket_acceptor&) BOOST_ASIO_DELETED;
2567
2568 class initiate_async_wait
2569 {
2570 public:
2571 typedef Executor executor_type;
2572
2573 explicit initiate_async_wait(basic_socket_acceptor* self)
2574 : self_(self)
2575 {
2576 }
2577
2578 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
2579 {
2580 return self_->get_executor();
2581 }
2582
2583 template <typename WaitHandler>
2584 void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, wait_type w) const
2585 {
2586 // If you get an error on the following line it means that your handler
2587 // does not meet the documented type requirements for a WaitHandler.
2588 BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
2589
2590 detail::non_const_lvalue<WaitHandler> handler2(handler);
2591 self_->impl_.get_service().async_wait(
2592 self_->impl_.get_implementation(), w,
2593 handler2.value, self_->impl_.get_executor());
2594 }
2595
2596 private:
2597 basic_socket_acceptor* self_;
2598 };
2599
2600 class initiate_async_accept
2601 {
2602 public:
2603 typedef Executor executor_type;
2604
2605 explicit initiate_async_accept(basic_socket_acceptor* self)
2606 : self_(self)
2607 {
2608 }
2609
2610 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
2611 {
2612 return self_->get_executor();
2613 }
2614
2615 template <typename AcceptHandler, typename Protocol1, typename Executor1>
2616 void operator()(BOOST_ASIO_MOVE_ARG(AcceptHandler) handler,
2617 basic_socket<Protocol1, Executor1>* peer,
2618 endpoint_type* peer_endpoint) const
2619 {
2620 // If you get an error on the following line it means that your handler
2621 // does not meet the documented type requirements for a AcceptHandler.
2622 BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check;
2623
2624 detail::non_const_lvalue<AcceptHandler> handler2(handler);
2625 self_->impl_.get_service().async_accept(
2626 self_->impl_.get_implementation(), *peer, peer_endpoint,
2627 handler2.value, self_->impl_.get_executor());
2628 }
2629
2630 private:
2631 basic_socket_acceptor* self_;
2632 };
2633
2634 class initiate_async_move_accept
2635 {
2636 public:
2637 typedef Executor executor_type;
2638
2639 explicit initiate_async_move_accept(basic_socket_acceptor* self)
2640 : self_(self)
2641 {
2642 }
2643
2644 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
2645 {
2646 return self_->get_executor();
2647 }
2648
2649 template <typename MoveAcceptHandler, typename Executor1, typename Socket>
2650 void operator()(BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler,
2651 const Executor1& peer_ex, endpoint_type* peer_endpoint, Socket*) const
2652 {
2653 // If you get an error on the following line it means that your handler
2654 // does not meet the documented type requirements for a MoveAcceptHandler.
2655 BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK(
2656 MoveAcceptHandler, handler, Socket) type_check;
2657
2658 detail::non_const_lvalue<MoveAcceptHandler> handler2(handler);
2659 self_->impl_.get_service().async_move_accept(
2660 self_->impl_.get_implementation(), peer_ex, peer_endpoint,
2661 handler2.value, self_->impl_.get_executor());
2662 }
2663
2664 private:
2665 basic_socket_acceptor* self_;
2666 };
2667
2668 #if defined(BOOST_ASIO_WINDOWS_RUNTIME)
2669 detail::io_object_impl<
2670 detail::null_socket_service<Protocol>, Executor> impl_;
2671 #elif defined(BOOST_ASIO_HAS_IOCP)
2672 detail::io_object_impl<
2673 detail::win_iocp_socket_service<Protocol>, Executor> impl_;
2674 #elif defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
2675 detail::io_object_impl<
2676 detail::io_uring_socket_service<Protocol>, Executor> impl_;
2677 #else
2678 detail::io_object_impl<
2679 detail::reactive_socket_service<Protocol>, Executor> impl_;
2680 #endif
2681 };
2682
2683 } // namespace asio
2684 } // namespace boost
2685
2686 #include <boost/asio/detail/pop_options.hpp>
2687
2688 #endif // BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_HPP