1 //
2 // basic_socket_acceptor.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 //
10 
11 #ifndef BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_HPP
12 #define BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_HPP
13 
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17 
18 #include <boost/asio/detail/config.hpp>
19 #include <boost/asio/any_io_executor.hpp>
20 #include <boost/asio/basic_socket.hpp>
21 #include <boost/asio/detail/handler_type_requirements.hpp>
22 #include <boost/asio/detail/io_object_impl.hpp>
23 #include <boost/asio/detail/non_const_lvalue.hpp>
24 #include <boost/asio/detail/throw_error.hpp>
25 #include <boost/asio/detail/type_traits.hpp>
26 #include <boost/asio/error.hpp>
27 #include <boost/asio/execution_context.hpp>
28 #include <boost/asio/socket_base.hpp>
29 
30 #if defined(BOOST_ASIO_WINDOWS_RUNTIME)
31 # include <boost/asio/detail/null_socket_service.hpp>
32 #elif defined(BOOST_ASIO_HAS_IOCP)
33 # include <boost/asio/detail/win_iocp_socket_service.hpp>
34 #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    */
basic_socket_acceptor(const executor_type & ex)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>
basic_socket_acceptor(ExecutionContext & context,typename constraint<is_convertible<ExecutionContext &,execution_context &>::value>::type=0)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    */
basic_socket_acceptor(const executor_type & ex,const protocol_type & protocol)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>
basic_socket_acceptor(ExecutionContext & context,const protocol_type & protocol,typename constraint<is_convertible<ExecutionContext &,execution_context &>::value,defaulted_constraint>::type=defaulted_constraint ())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    */
basic_socket_acceptor(const executor_type & ex,const endpoint_type & endpoint,bool reuse_addr=true)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>
basic_socket_acceptor(ExecutionContext & context,const endpoint_type & endpoint,bool reuse_addr=true,typename constraint<is_convertible<ExecutionContext &,execution_context &>::value>::type=0)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    */
basic_socket_acceptor(const executor_type & ex,const protocol_type & protocol,const native_handle_type & native_acceptor)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>
basic_socket_acceptor(ExecutionContext & context,const protocol_type & protocol,const native_handle_type & native_acceptor,typename constraint<is_convertible<ExecutionContext &,execution_context &>::value>::type=0)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    */
basic_socket_acceptor(basic_socket_acceptor && other)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    */
operator =(basic_socket_acceptor && other)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>
basic_socket_acceptor(basic_socket_acceptor<Protocol1,Executor1> && other,typename constraint<is_convertible<Protocol1,Protocol>::value && is_convertible<Executor1,Executor>::value>::type=0)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&
operator =(basic_socket_acceptor<Protocol1,Executor1> && other)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    */
~basic_socket_acceptor()448   ~basic_socket_acceptor()
449   {
450   }
451 
452   /// Get the executor associated with the object.
get_executor()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    */
open(const protocol_type & protocol=protocol_type ())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    */
open(const protocol_type & protocol,boost::system::error_code & ec)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    */
assign(const protocol_type & protocol,const native_handle_type & native_acceptor)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    */
assign(const protocol_type & protocol,const native_handle_type & native_acceptor,boost::system::error_code & ec)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.
is_open() const545   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    */
bind(const endpoint_type & endpoint)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    */
bind(const endpoint_type & endpoint,boost::system::error_code & ec)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    */
listen(int backlog=socket_base::max_listen_connections)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    */
listen(int backlog,boost::system::error_code & ec)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    */
close()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    */
close(boost::system::error_code & ec)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
release()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
release(boost::system::error_code & ec)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    */
native_handle()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    */
cancel()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    */
cancel(boost::system::error_code & ec)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>
set_option(const SettableSocketOption & option)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>
set_option(const SettableSocketOption & option,boost::system::error_code & ec)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>
get_option(GettableSocketOption & option) const873   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>
get_option(GettableSocketOption & option,boost::system::error_code & ec) const908   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>
io_control(IoControlCommand & command)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>
io_control(IoControlCommand & command,boost::system::error_code & ec)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    */
non_blocking() const987   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    */
non_blocking(bool mode)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    */
non_blocking(bool mode,boost::system::error_code & ec)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    */
native_non_blocking() const1046   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    */
native_non_blocking(bool mode)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    */
native_non_blocking(bool mode,boost::system::error_code & ec)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    */
local_endpoint() const1112   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    */
local_endpoint(boost::system::error_code & ec) const1143   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    */
wait(wait_type w)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    */
wait(wait_type w,boost::system::error_code & ec)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.
1201    *
1202    * @param w Specifies the desired acceptor state.
1203    *
1204    * @param handler The handler to be called when the wait operation completes.
1205    * Copies will be made of the handler as required. The function signature of
1206    * the handler must be:
1207    * @code void handler(
1208    *   const boost::system::error_code& error // Result of operation
1209    * ); @endcode
1210    * Regardless of whether the asynchronous operation completes immediately or
1211    * not, the handler will not be invoked from within this function. On
1212    * immediate completion, invocation of the handler will be performed in a
1213    * manner equivalent to using boost::asio::post().
1214    *
1215    * @par Example
1216    * @code
1217    * void wait_handler(const boost::system::error_code& error)
1218    * {
1219    *   if (!error)
1220    *   {
1221    *     // Wait succeeded.
1222    *   }
1223    * }
1224    *
1225    * ...
1226    *
1227    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1228    * ...
1229    * acceptor.async_wait(
1230    *     boost::asio::ip::tcp::acceptor::wait_read,
1231    *     wait_handler);
1232    * @endcode
1233    *
1234    * @par Per-Operation Cancellation
1235    * On POSIX or Windows operating systems, this asynchronous operation supports
1236    * cancellation for the following boost::asio::cancellation_type values:
1237    *
1238    * @li @c cancellation_type::terminal
1239    *
1240    * @li @c cancellation_type::partial
1241    *
1242    * @li @c cancellation_type::total
1243    */
1244   template <
1245       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
1246         WaitHandler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WaitHandler,void (boost::system::error_code))1247   BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WaitHandler,
1248       void (boost::system::error_code))
1249   async_wait(wait_type w,
1250       BOOST_ASIO_MOVE_ARG(WaitHandler) handler
1251         BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
1252   {
1253     return async_initiate<WaitHandler, void (boost::system::error_code)>(
1254         initiate_async_wait(this), handler, w);
1255   }
1256 
1257 #if !defined(BOOST_ASIO_NO_EXTENSIONS)
1258   /// Accept a new connection.
1259   /**
1260    * This function is used to accept a new connection from a peer into the
1261    * given socket. The function call will block until a new connection has been
1262    * accepted successfully or an error occurs.
1263    *
1264    * @param peer The socket into which the new connection will be accepted.
1265    *
1266    * @throws boost::system::system_error Thrown on failure.
1267    *
1268    * @par Example
1269    * @code
1270    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1271    * ...
1272    * boost::asio::ip::tcp::socket socket(my_context);
1273    * acceptor.accept(socket);
1274    * @endcode
1275    */
1276   template <typename Protocol1, typename Executor1>
accept(basic_socket<Protocol1,Executor1> & peer,typename constraint<is_convertible<Protocol,Protocol1>::value>::type=0)1277   void accept(basic_socket<Protocol1, Executor1>& peer,
1278       typename constraint<
1279         is_convertible<Protocol, Protocol1>::value
1280       >::type = 0)
1281   {
1282     boost::system::error_code ec;
1283     impl_.get_service().accept(impl_.get_implementation(),
1284         peer, static_cast<endpoint_type*>(0), ec);
1285     boost::asio::detail::throw_error(ec, "accept");
1286   }
1287 
1288   /// Accept a new connection.
1289   /**
1290    * This function is used to accept a new connection from a peer into the
1291    * given socket. The function call will block until a new connection has been
1292    * accepted successfully or an error occurs.
1293    *
1294    * @param peer The socket into which the new connection will be accepted.
1295    *
1296    * @param ec Set to indicate what error occurred, if any.
1297    *
1298    * @par Example
1299    * @code
1300    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1301    * ...
1302    * boost::asio::ip::tcp::socket socket(my_context);
1303    * boost::system::error_code ec;
1304    * acceptor.accept(socket, ec);
1305    * if (ec)
1306    * {
1307    *   // An error occurred.
1308    * }
1309    * @endcode
1310    */
1311   template <typename Protocol1, typename Executor1>
accept(basic_socket<Protocol1,Executor1> & peer,boost::system::error_code & ec,typename constraint<is_convertible<Protocol,Protocol1>::value>::type=0)1312   BOOST_ASIO_SYNC_OP_VOID accept(
1313       basic_socket<Protocol1, Executor1>& peer, boost::system::error_code& ec,
1314       typename constraint<
1315         is_convertible<Protocol, Protocol1>::value
1316       >::type = 0)
1317   {
1318     impl_.get_service().accept(impl_.get_implementation(),
1319         peer, static_cast<endpoint_type*>(0), ec);
1320     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
1321   }
1322 
1323   /// Start an asynchronous accept.
1324   /**
1325    * This function is used to asynchronously accept a new connection into a
1326    * socket. The function call always returns immediately.
1327    *
1328    * @param peer The socket into which the new connection will be accepted.
1329    * Ownership of the peer object is retained by the caller, which must
1330    * guarantee that it is valid until the handler is called.
1331    *
1332    * @param handler The handler to be called when the accept operation
1333    * completes. Copies will be made of the handler as required. The function
1334    * signature of the handler must be:
1335    * @code void handler(
1336    *   const boost::system::error_code& error // Result of operation.
1337    * ); @endcode
1338    * Regardless of whether the asynchronous operation completes immediately or
1339    * not, the handler will not be invoked from within this function. On
1340    * immediate completion, invocation of the handler will be performed in a
1341    * manner equivalent to using boost::asio::post().
1342    *
1343    * @par Example
1344    * @code
1345    * void accept_handler(const boost::system::error_code& error)
1346    * {
1347    *   if (!error)
1348    *   {
1349    *     // Accept succeeded.
1350    *   }
1351    * }
1352    *
1353    * ...
1354    *
1355    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1356    * ...
1357    * boost::asio::ip::tcp::socket socket(my_context);
1358    * acceptor.async_accept(socket, accept_handler);
1359    * @endcode
1360    *
1361    * @par Per-Operation Cancellation
1362    * On POSIX or Windows operating systems, this asynchronous operation supports
1363    * cancellation for the following boost::asio::cancellation_type values:
1364    *
1365    * @li @c cancellation_type::terminal
1366    *
1367    * @li @c cancellation_type::partial
1368    *
1369    * @li @c cancellation_type::total
1370    */
1371   template <typename Protocol1, typename Executor1,
1372       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
1373         AcceptHandler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(AcceptHandler,void (boost::system::error_code))1374   BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(AcceptHandler,
1375       void (boost::system::error_code))
1376   async_accept(basic_socket<Protocol1, Executor1>& peer,
1377       BOOST_ASIO_MOVE_ARG(AcceptHandler) handler
1378         BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
1379       typename constraint<
1380         is_convertible<Protocol, Protocol1>::value
1381       >::type = 0)
1382   {
1383     return async_initiate<AcceptHandler, void (boost::system::error_code)>(
1384         initiate_async_accept(this), handler,
1385         &peer, static_cast<endpoint_type*>(0));
1386   }
1387 
1388   /// Accept a new connection and obtain the endpoint of the peer
1389   /**
1390    * This function is used to accept a new connection from a peer into the
1391    * given socket, and additionally provide the endpoint of the remote peer.
1392    * The function call will block until a new connection has been accepted
1393    * successfully or an error occurs.
1394    *
1395    * @param peer The socket into which the new connection will be accepted.
1396    *
1397    * @param peer_endpoint An endpoint object which will receive the endpoint of
1398    * the remote peer.
1399    *
1400    * @throws boost::system::system_error Thrown on failure.
1401    *
1402    * @par Example
1403    * @code
1404    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1405    * ...
1406    * boost::asio::ip::tcp::socket socket(my_context);
1407    * boost::asio::ip::tcp::endpoint endpoint;
1408    * acceptor.accept(socket, endpoint);
1409    * @endcode
1410    */
1411   template <typename Executor1>
accept(basic_socket<protocol_type,Executor1> & peer,endpoint_type & peer_endpoint)1412   void accept(basic_socket<protocol_type, Executor1>& peer,
1413       endpoint_type& peer_endpoint)
1414   {
1415     boost::system::error_code ec;
1416     impl_.get_service().accept(impl_.get_implementation(),
1417         peer, &peer_endpoint, ec);
1418     boost::asio::detail::throw_error(ec, "accept");
1419   }
1420 
1421   /// Accept a new connection and obtain the endpoint of the peer
1422   /**
1423    * This function is used to accept a new connection from a peer into the
1424    * given socket, and additionally provide the endpoint of the remote peer.
1425    * The function call will block until a new connection has been accepted
1426    * successfully or an error occurs.
1427    *
1428    * @param peer The socket into which the new connection will be accepted.
1429    *
1430    * @param peer_endpoint An endpoint object which will receive the endpoint of
1431    * the remote peer.
1432    *
1433    * @param ec Set to indicate what error occurred, if any.
1434    *
1435    * @par Example
1436    * @code
1437    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1438    * ...
1439    * boost::asio::ip::tcp::socket socket(my_context);
1440    * boost::asio::ip::tcp::endpoint endpoint;
1441    * boost::system::error_code ec;
1442    * acceptor.accept(socket, endpoint, ec);
1443    * if (ec)
1444    * {
1445    *   // An error occurred.
1446    * }
1447    * @endcode
1448    */
1449   template <typename Executor1>
accept(basic_socket<protocol_type,Executor1> & peer,endpoint_type & peer_endpoint,boost::system::error_code & ec)1450   BOOST_ASIO_SYNC_OP_VOID accept(basic_socket<protocol_type, Executor1>& peer,
1451       endpoint_type& peer_endpoint, boost::system::error_code& ec)
1452   {
1453     impl_.get_service().accept(
1454         impl_.get_implementation(), peer, &peer_endpoint, ec);
1455     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
1456   }
1457 
1458   /// Start an asynchronous accept.
1459   /**
1460    * This function is used to asynchronously accept a new connection into a
1461    * socket, and additionally obtain the endpoint of the remote peer. The
1462    * function call always returns immediately.
1463    *
1464    * @param peer The socket into which the new connection will be accepted.
1465    * Ownership of the peer object is retained by the caller, which must
1466    * guarantee that it is valid until the handler is called.
1467    *
1468    * @param peer_endpoint An endpoint object into which the endpoint of the
1469    * remote peer will be written. Ownership of the peer_endpoint object is
1470    * retained by the caller, which must guarantee that it is valid until the
1471    * handler is called.
1472    *
1473    * @param handler The handler to be called when the accept operation
1474    * completes. Copies will be made of the handler as required. The function
1475    * signature of the handler must be:
1476    * @code void handler(
1477    *   const boost::system::error_code& error // Result of operation.
1478    * ); @endcode
1479    * Regardless of whether the asynchronous operation completes immediately or
1480    * not, the handler will not be invoked from within this function. On
1481    * immediate completion, invocation of the handler will be performed in a
1482    * manner equivalent to using boost::asio::post().
1483    *
1484    * @par Per-Operation Cancellation
1485    * On POSIX or Windows operating systems, this asynchronous operation supports
1486    * cancellation for the following boost::asio::cancellation_type values:
1487    *
1488    * @li @c cancellation_type::terminal
1489    *
1490    * @li @c cancellation_type::partial
1491    *
1492    * @li @c cancellation_type::total
1493    */
1494   template <typename Executor1,
1495       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
1496         AcceptHandler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(AcceptHandler,void (boost::system::error_code))1497   BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(AcceptHandler,
1498       void (boost::system::error_code))
1499   async_accept(basic_socket<protocol_type, Executor1>& peer,
1500       endpoint_type& peer_endpoint,
1501       BOOST_ASIO_MOVE_ARG(AcceptHandler) handler
1502         BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
1503   {
1504     return async_initiate<AcceptHandler, void (boost::system::error_code)>(
1505         initiate_async_accept(this), handler, &peer, &peer_endpoint);
1506   }
1507 #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
1508 
1509 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
1510   /// Accept a new connection.
1511   /**
1512    * This function is used to accept a new connection from a peer. The function
1513    * call will block until a new connection has been accepted successfully or
1514    * an error occurs.
1515    *
1516    * This overload requires that the Protocol template parameter satisfy the
1517    * AcceptableProtocol type requirements.
1518    *
1519    * @returns A socket object representing the newly accepted connection.
1520    *
1521    * @throws boost::system::system_error Thrown on failure.
1522    *
1523    * @par Example
1524    * @code
1525    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1526    * ...
1527    * boost::asio::ip::tcp::socket socket(acceptor.accept());
1528    * @endcode
1529    */
1530   typename Protocol::socket::template rebind_executor<executor_type>::other
accept()1531   accept()
1532   {
1533     boost::system::error_code ec;
1534     typename Protocol::socket::template rebind_executor<
1535       executor_type>::other peer(impl_.get_executor());
1536     impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
1537     boost::asio::detail::throw_error(ec, "accept");
1538     return peer;
1539   }
1540 
1541   /// Accept a new connection.
1542   /**
1543    * This function is used to accept a new connection from a peer. The function
1544    * call will block until a new connection has been accepted successfully or
1545    * an error occurs.
1546    *
1547    * This overload requires that the Protocol template parameter satisfy the
1548    * AcceptableProtocol type requirements.
1549    *
1550    * @param ec Set to indicate what error occurred, if any.
1551    *
1552    * @returns On success, a socket object representing the newly accepted
1553    * connection. On error, a socket object where is_open() is false.
1554    *
1555    * @par Example
1556    * @code
1557    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1558    * ...
1559    * boost::asio::ip::tcp::socket socket(acceptor.accept(ec));
1560    * if (ec)
1561    * {
1562    *   // An error occurred.
1563    * }
1564    * @endcode
1565    */
1566   typename Protocol::socket::template rebind_executor<executor_type>::other
accept(boost::system::error_code & ec)1567   accept(boost::system::error_code& ec)
1568   {
1569     typename Protocol::socket::template rebind_executor<
1570       executor_type>::other peer(impl_.get_executor());
1571     impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
1572     return peer;
1573   }
1574 
1575   /// Start an asynchronous accept.
1576   /**
1577    * This function is used to asynchronously accept a new connection. The
1578    * function call always returns immediately.
1579    *
1580    * This overload requires that the Protocol template parameter satisfy the
1581    * AcceptableProtocol type requirements.
1582    *
1583    * @param handler The handler to be called when the accept operation
1584    * completes. Copies will be made of the handler as required. The function
1585    * signature of the handler must be:
1586    * @code void handler(
1587    *   // Result of operation.
1588    *   const boost::system::error_code& error,
1589    *   // On success, the newly accepted socket.
1590    *   typename Protocol::socket::template
1591    *     rebind_executor<executor_type>::other peer
1592    * ); @endcode
1593    * Regardless of whether the asynchronous operation completes immediately or
1594    * not, the handler will not be invoked from within this function. On
1595    * immediate completion, invocation of the handler will be performed in a
1596    * manner equivalent to using boost::asio::post().
1597    *
1598    * @par Example
1599    * @code
1600    * void accept_handler(const boost::system::error_code& error,
1601    *     boost::asio::ip::tcp::socket peer)
1602    * {
1603    *   if (!error)
1604    *   {
1605    *     // Accept succeeded.
1606    *   }
1607    * }
1608    *
1609    * ...
1610    *
1611    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1612    * ...
1613    * acceptor.async_accept(accept_handler);
1614    * @endcode
1615    *
1616    * @par Per-Operation Cancellation
1617    * On POSIX or Windows operating systems, this asynchronous operation supports
1618    * cancellation for the following boost::asio::cancellation_type values:
1619    *
1620    * @li @c cancellation_type::terminal
1621    *
1622    * @li @c cancellation_type::partial
1623    *
1624    * @li @c cancellation_type::total
1625    */
1626   template <
1627       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
1628         typename Protocol::socket::template rebind_executor<
1629           executor_type>::other)) MoveAcceptHandler
1630             BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,void (boost::system::error_code,typename Protocol::socket::template rebind_executor<executor_type>::other))1631   BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,
1632       void (boost::system::error_code,
1633         typename Protocol::socket::template
1634           rebind_executor<executor_type>::other))
1635   async_accept(
1636       BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler
1637         BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
1638   {
1639     return async_initiate<MoveAcceptHandler,
1640       void (boost::system::error_code, typename Protocol::socket::template
1641         rebind_executor<executor_type>::other)>(
1642           initiate_async_move_accept(this), handler,
1643           impl_.get_executor(), static_cast<endpoint_type*>(0),
1644           static_cast<typename Protocol::socket::template
1645             rebind_executor<executor_type>::other*>(0));
1646   }
1647 
1648   /// Accept a new connection.
1649   /**
1650    * This function is used to accept a new connection from a peer. The function
1651    * call will block until a new connection has been accepted successfully or
1652    * an error occurs.
1653    *
1654    * This overload requires that the Protocol template parameter satisfy the
1655    * AcceptableProtocol type requirements.
1656    *
1657    * @param ex The I/O executor object to be used for the newly
1658    * accepted socket.
1659    *
1660    * @returns A socket object representing the newly accepted connection.
1661    *
1662    * @throws boost::system::system_error Thrown on failure.
1663    *
1664    * @par Example
1665    * @code
1666    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1667    * ...
1668    * boost::asio::ip::tcp::socket socket(acceptor.accept());
1669    * @endcode
1670    */
1671   template <typename Executor1>
1672   typename Protocol::socket::template rebind_executor<Executor1>::other
accept(const Executor1 & ex,typename constraint<is_executor<Executor1>::value||execution::is_executor<Executor1>::value>::type=0)1673   accept(const Executor1& ex,
1674       typename constraint<
1675         is_executor<Executor1>::value
1676           || execution::is_executor<Executor1>::value
1677       >::type = 0)
1678   {
1679     boost::system::error_code ec;
1680     typename Protocol::socket::template
1681       rebind_executor<Executor1>::other peer(ex);
1682     impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
1683     boost::asio::detail::throw_error(ec, "accept");
1684     return peer;
1685   }
1686 
1687   /// Accept a new connection.
1688   /**
1689    * This function is used to accept a new connection from a peer. The function
1690    * call will block until a new connection has been accepted successfully or
1691    * an error occurs.
1692    *
1693    * This overload requires that the Protocol template parameter satisfy the
1694    * AcceptableProtocol type requirements.
1695    *
1696    * @param context The I/O execution context object to be used for the newly
1697    * accepted socket.
1698    *
1699    * @returns A socket object representing the newly accepted connection.
1700    *
1701    * @throws boost::system::system_error Thrown on failure.
1702    *
1703    * @par Example
1704    * @code
1705    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1706    * ...
1707    * boost::asio::ip::tcp::socket socket(acceptor.accept());
1708    * @endcode
1709    */
1710   template <typename ExecutionContext>
1711   typename Protocol::socket::template rebind_executor<
1712       typename ExecutionContext::executor_type>::other
accept(ExecutionContext & context,typename constraint<is_convertible<ExecutionContext &,execution_context &>::value>::type=0)1713   accept(ExecutionContext& context,
1714       typename constraint<
1715         is_convertible<ExecutionContext&, execution_context&>::value
1716       >::type = 0)
1717   {
1718     boost::system::error_code ec;
1719     typename Protocol::socket::template rebind_executor<
1720         typename ExecutionContext::executor_type>::other peer(context);
1721     impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
1722     boost::asio::detail::throw_error(ec, "accept");
1723     return peer;
1724   }
1725 
1726   /// Accept a new connection.
1727   /**
1728    * This function is used to accept a new connection from a peer. The function
1729    * call will block until a new connection has been accepted successfully or
1730    * an error occurs.
1731    *
1732    * This overload requires that the Protocol template parameter satisfy the
1733    * AcceptableProtocol type requirements.
1734    *
1735    * @param ex The I/O executor object to be used for the newly accepted
1736    * socket.
1737    *
1738    * @param ec Set to indicate what error occurred, if any.
1739    *
1740    * @returns On success, a socket object representing the newly accepted
1741    * connection. On error, a socket object where is_open() is false.
1742    *
1743    * @par Example
1744    * @code
1745    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1746    * ...
1747    * boost::asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec));
1748    * if (ec)
1749    * {
1750    *   // An error occurred.
1751    * }
1752    * @endcode
1753    */
1754   template <typename Executor1>
1755   typename Protocol::socket::template rebind_executor<Executor1>::other
accept(const Executor1 & ex,boost::system::error_code & ec,typename constraint<is_executor<Executor1>::value||execution::is_executor<Executor1>::value>::type=0)1756   accept(const Executor1& ex, boost::system::error_code& ec,
1757       typename constraint<
1758         is_executor<Executor1>::value
1759           || execution::is_executor<Executor1>::value
1760       >::type = 0)
1761   {
1762     typename Protocol::socket::template
1763       rebind_executor<Executor1>::other peer(ex);
1764     impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
1765     return peer;
1766   }
1767 
1768   /// Accept a new connection.
1769   /**
1770    * This function is used to accept a new connection from a peer. The function
1771    * call will block until a new connection has been accepted successfully or
1772    * an error occurs.
1773    *
1774    * This overload requires that the Protocol template parameter satisfy the
1775    * AcceptableProtocol type requirements.
1776    *
1777    * @param context The I/O execution context object to be used for the newly
1778    * accepted socket.
1779    *
1780    * @param ec Set to indicate what error occurred, if any.
1781    *
1782    * @returns On success, a socket object representing the newly accepted
1783    * connection. On error, a socket object where is_open() is false.
1784    *
1785    * @par Example
1786    * @code
1787    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1788    * ...
1789    * boost::asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec));
1790    * if (ec)
1791    * {
1792    *   // An error occurred.
1793    * }
1794    * @endcode
1795    */
1796   template <typename ExecutionContext>
1797   typename Protocol::socket::template rebind_executor<
1798       typename ExecutionContext::executor_type>::other
accept(ExecutionContext & context,boost::system::error_code & ec,typename constraint<is_convertible<ExecutionContext &,execution_context &>::value>::type=0)1799   accept(ExecutionContext& context, boost::system::error_code& ec,
1800       typename constraint<
1801         is_convertible<ExecutionContext&, execution_context&>::value
1802       >::type = 0)
1803   {
1804     typename Protocol::socket::template rebind_executor<
1805         typename ExecutionContext::executor_type>::other peer(context);
1806     impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
1807     return peer;
1808   }
1809 
1810   /// Start an asynchronous accept.
1811   /**
1812    * This function is used to asynchronously accept a new connection. The
1813    * function call always returns immediately.
1814    *
1815    * This overload requires that the Protocol template parameter satisfy the
1816    * AcceptableProtocol type requirements.
1817    *
1818    * @param ex The I/O executor object to be used for the newly accepted
1819    * socket.
1820    *
1821    * @param handler The handler to be called when the accept operation
1822    * completes. Copies will be made of the handler as required. The function
1823    * signature of the handler must be:
1824    * @code void handler(
1825    *   const boost::system::error_code& error, // Result of operation.
1826    *   typename Protocol::socket::template rebind_executor<
1827    *     Executor1>::other peer // On success, the newly accepted socket.
1828    * ); @endcode
1829    * Regardless of whether the asynchronous operation completes immediately or
1830    * not, the handler will not be invoked from within this function. On
1831    * immediate completion, invocation of the handler will be performed in a
1832    * manner equivalent to using boost::asio::post().
1833    *
1834    * @par Example
1835    * @code
1836    * void accept_handler(const boost::system::error_code& error,
1837    *     boost::asio::ip::tcp::socket peer)
1838    * {
1839    *   if (!error)
1840    *   {
1841    *     // Accept succeeded.
1842    *   }
1843    * }
1844    *
1845    * ...
1846    *
1847    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1848    * ...
1849    * acceptor.async_accept(my_context2, accept_handler);
1850    * @endcode
1851    *
1852    * @par Per-Operation Cancellation
1853    * On POSIX or Windows operating systems, this asynchronous operation supports
1854    * cancellation for the following boost::asio::cancellation_type values:
1855    *
1856    * @li @c cancellation_type::terminal
1857    *
1858    * @li @c cancellation_type::partial
1859    *
1860    * @li @c cancellation_type::total
1861    */
1862   template <typename Executor1,
1863       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
1864         typename Protocol::socket::template rebind_executor<
1865           Executor1>::other)) MoveAcceptHandler
1866             BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,void (boost::system::error_code,typename Protocol::socket::template rebind_executor<Executor1>::other))1867   BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,
1868       void (boost::system::error_code,
1869         typename Protocol::socket::template rebind_executor<
1870           Executor1>::other))
1871   async_accept(const Executor1& ex,
1872       BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler
1873         BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
1874       typename constraint<
1875         is_executor<Executor1>::value
1876           || execution::is_executor<Executor1>::value
1877       >::type = 0)
1878   {
1879     typedef typename Protocol::socket::template rebind_executor<
1880       Executor1>::other other_socket_type;
1881 
1882     return async_initiate<MoveAcceptHandler,
1883       void (boost::system::error_code, other_socket_type)>(
1884         initiate_async_move_accept(this), handler,
1885         ex, static_cast<endpoint_type*>(0),
1886         static_cast<other_socket_type*>(0));
1887   }
1888 
1889   /// Start an asynchronous accept.
1890   /**
1891    * This function is used to asynchronously accept a new connection. The
1892    * function call always returns immediately.
1893    *
1894    * This overload requires that the Protocol template parameter satisfy the
1895    * AcceptableProtocol type requirements.
1896    *
1897    * @param context The I/O execution context object to be used for the newly
1898    * accepted socket.
1899    *
1900    * @param handler The handler to be called when the accept operation
1901    * completes. Copies will be made of the handler as required. The function
1902    * signature of the handler must be:
1903    * @code void handler(
1904    *   const boost::system::error_code& error, // Result of operation.
1905    *   typename Protocol::socket::template rebind_executor<
1906    *     typename ExecutionContext::executor_type>::other peer
1907    *       // On success, the newly accepted socket.
1908    * ); @endcode
1909    * Regardless of whether the asynchronous operation completes immediately or
1910    * not, the handler will not be invoked from within this function. On
1911    * immediate completion, invocation of the handler will be performed in a
1912    * manner equivalent to using boost::asio::post().
1913    *
1914    * @par Example
1915    * @code
1916    * void accept_handler(const boost::system::error_code& error,
1917    *     boost::asio::ip::tcp::socket peer)
1918    * {
1919    *   if (!error)
1920    *   {
1921    *     // Accept succeeded.
1922    *   }
1923    * }
1924    *
1925    * ...
1926    *
1927    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1928    * ...
1929    * acceptor.async_accept(my_context2, accept_handler);
1930    * @endcode
1931    *
1932    * @par Per-Operation Cancellation
1933    * On POSIX or Windows operating systems, this asynchronous operation supports
1934    * cancellation for the following boost::asio::cancellation_type values:
1935    *
1936    * @li @c cancellation_type::terminal
1937    *
1938    * @li @c cancellation_type::partial
1939    *
1940    * @li @c cancellation_type::total
1941    */
1942   template <typename ExecutionContext,
1943       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
1944         typename Protocol::socket::template rebind_executor<
1945           typename ExecutionContext::executor_type>::other)) MoveAcceptHandler
1946             BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,void (boost::system::error_code,typename Protocol::socket::template rebind_executor<typename ExecutionContext::executor_type>::other))1947   BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,
1948       void (boost::system::error_code,
1949         typename Protocol::socket::template rebind_executor<
1950           typename ExecutionContext::executor_type>::other))
1951   async_accept(ExecutionContext& context,
1952       BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler
1953         BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
1954       typename constraint<
1955         is_convertible<ExecutionContext&, execution_context&>::value
1956       >::type = 0)
1957   {
1958     typedef typename Protocol::socket::template rebind_executor<
1959       typename ExecutionContext::executor_type>::other other_socket_type;
1960 
1961     return async_initiate<MoveAcceptHandler,
1962       void (boost::system::error_code, other_socket_type)>(
1963         initiate_async_move_accept(this), handler,
1964         context.get_executor(), static_cast<endpoint_type*>(0),
1965         static_cast<other_socket_type*>(0));
1966   }
1967 
1968   /// Accept a new connection.
1969   /**
1970    * This function is used to accept a new connection from a peer. The function
1971    * call will block until a new connection has been accepted successfully or
1972    * an error occurs.
1973    *
1974    * This overload requires that the Protocol template parameter satisfy the
1975    * AcceptableProtocol type requirements.
1976    *
1977    * @param peer_endpoint An endpoint object into which the endpoint of the
1978    * remote peer will be written.
1979    *
1980    * @returns A socket object representing the newly accepted connection.
1981    *
1982    * @throws boost::system::system_error Thrown on failure.
1983    *
1984    * @par Example
1985    * @code
1986    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1987    * ...
1988    * boost::asio::ip::tcp::endpoint endpoint;
1989    * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint));
1990    * @endcode
1991    */
1992   typename Protocol::socket::template rebind_executor<executor_type>::other
accept(endpoint_type & peer_endpoint)1993   accept(endpoint_type& peer_endpoint)
1994   {
1995     boost::system::error_code ec;
1996     typename Protocol::socket::template rebind_executor<
1997       executor_type>::other peer(impl_.get_executor());
1998     impl_.get_service().accept(impl_.get_implementation(),
1999         peer, &peer_endpoint, ec);
2000     boost::asio::detail::throw_error(ec, "accept");
2001     return peer;
2002   }
2003 
2004   /// Accept a new connection.
2005   /**
2006    * This function is used to accept a new connection from a peer. The function
2007    * call will block until a new connection has been accepted successfully or
2008    * an error occurs.
2009    *
2010    * This overload requires that the Protocol template parameter satisfy the
2011    * AcceptableProtocol type requirements.
2012    *
2013    * @param peer_endpoint An endpoint object into which the endpoint of the
2014    * remote peer will be written.
2015    *
2016    * @param ec Set to indicate what error occurred, if any.
2017    *
2018    * @returns On success, a socket object representing the newly accepted
2019    * connection. On error, a socket object where is_open() is false.
2020    *
2021    * @par Example
2022    * @code
2023    * boost::asio::ip::tcp::acceptor acceptor(my_context);
2024    * ...
2025    * boost::asio::ip::tcp::endpoint endpoint;
2026    * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint, ec));
2027    * if (ec)
2028    * {
2029    *   // An error occurred.
2030    * }
2031    * @endcode
2032    */
2033   typename Protocol::socket::template rebind_executor<executor_type>::other
accept(endpoint_type & peer_endpoint,boost::system::error_code & ec)2034   accept(endpoint_type& peer_endpoint, boost::system::error_code& ec)
2035   {
2036     typename Protocol::socket::template rebind_executor<
2037       executor_type>::other peer(impl_.get_executor());
2038     impl_.get_service().accept(impl_.get_implementation(),
2039         peer, &peer_endpoint, ec);
2040     return peer;
2041   }
2042 
2043   /// Start an asynchronous accept.
2044   /**
2045    * This function is used to asynchronously accept a new connection. The
2046    * function call always returns immediately.
2047    *
2048    * This overload requires that the Protocol template parameter satisfy the
2049    * AcceptableProtocol type requirements.
2050    *
2051    * @param peer_endpoint An endpoint object into which the endpoint of the
2052    * remote peer will be written. Ownership of the peer_endpoint object is
2053    * retained by the caller, which must guarantee that it is valid until the
2054    * handler is called.
2055    *
2056    * @param handler The handler to be called when the accept operation
2057    * completes. Copies will be made of the handler as required. The function
2058    * signature of the handler must be:
2059    * @code void handler(
2060    *   // Result of operation.
2061    *   const boost::system::error_code& error,
2062    *   // On success, the newly accepted socket.
2063    *   typename Protocol::socket::template
2064    *     rebind_executor<executor_type>::other peer
2065    * ); @endcode
2066    * Regardless of whether the asynchronous operation completes immediately or
2067    * not, the handler will not be invoked from within this function. On
2068    * immediate completion, invocation of the handler will be performed in a
2069    * manner equivalent to using boost::asio::post().
2070    *
2071    * @par Example
2072    * @code
2073    * void accept_handler(const boost::system::error_code& error,
2074    *     boost::asio::ip::tcp::socket peer)
2075    * {
2076    *   if (!error)
2077    *   {
2078    *     // Accept succeeded.
2079    *   }
2080    * }
2081    *
2082    * ...
2083    *
2084    * boost::asio::ip::tcp::acceptor acceptor(my_context);
2085    * ...
2086    * boost::asio::ip::tcp::endpoint endpoint;
2087    * acceptor.async_accept(endpoint, accept_handler);
2088    * @endcode
2089    *
2090    * @par Per-Operation Cancellation
2091    * On POSIX or Windows operating systems, this asynchronous operation supports
2092    * cancellation for the following boost::asio::cancellation_type values:
2093    *
2094    * @li @c cancellation_type::terminal
2095    *
2096    * @li @c cancellation_type::partial
2097    *
2098    * @li @c cancellation_type::total
2099    */
2100   template <
2101       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
2102         typename Protocol::socket::template rebind_executor<
2103           executor_type>::other)) MoveAcceptHandler
2104             BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,void (boost::system::error_code,typename Protocol::socket::template rebind_executor<executor_type>::other))2105   BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,
2106       void (boost::system::error_code,
2107         typename Protocol::socket::template
2108           rebind_executor<executor_type>::other))
2109   async_accept(endpoint_type& peer_endpoint,
2110       BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler
2111         BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
2112   {
2113     return async_initiate<MoveAcceptHandler,
2114       void (boost::system::error_code, typename Protocol::socket::template
2115         rebind_executor<executor_type>::other)>(
2116           initiate_async_move_accept(this), handler,
2117           impl_.get_executor(), &peer_endpoint,
2118           static_cast<typename Protocol::socket::template
2119             rebind_executor<executor_type>::other*>(0));
2120   }
2121 
2122   /// Accept a new connection.
2123   /**
2124    * This function is used to accept a new connection from a peer. The function
2125    * call will block until a new connection has been accepted successfully or
2126    * an error occurs.
2127    *
2128    * This overload requires that the Protocol template parameter satisfy the
2129    * AcceptableProtocol type requirements.
2130    *
2131    * @param ex The I/O executor object to be used for the newly accepted
2132    * socket.
2133    *
2134    * @param peer_endpoint An endpoint object into which the endpoint of the
2135    * remote peer will be written.
2136    *
2137    * @returns A socket object representing the newly accepted connection.
2138    *
2139    * @throws boost::system::system_error Thrown on failure.
2140    *
2141    * @par Example
2142    * @code
2143    * boost::asio::ip::tcp::acceptor acceptor(my_context);
2144    * ...
2145    * boost::asio::ip::tcp::endpoint endpoint;
2146    * boost::asio::ip::tcp::socket socket(
2147    *     acceptor.accept(my_context2, endpoint));
2148    * @endcode
2149    */
2150   template <typename Executor1>
2151   typename Protocol::socket::template rebind_executor<Executor1>::other
accept(const Executor1 & ex,endpoint_type & peer_endpoint,typename constraint<is_executor<Executor1>::value||execution::is_executor<Executor1>::value>::type=0)2152   accept(const Executor1& ex, endpoint_type& peer_endpoint,
2153       typename constraint<
2154         is_executor<Executor1>::value
2155           || execution::is_executor<Executor1>::value
2156       >::type = 0)
2157   {
2158     boost::system::error_code ec;
2159     typename Protocol::socket::template
2160         rebind_executor<Executor1>::other peer(ex);
2161     impl_.get_service().accept(impl_.get_implementation(),
2162         peer, &peer_endpoint, ec);
2163     boost::asio::detail::throw_error(ec, "accept");
2164     return peer;
2165   }
2166 
2167   /// Accept a new connection.
2168   /**
2169    * This function is used to accept a new connection from a peer. The function
2170    * call will block until a new connection has been accepted successfully or
2171    * an error occurs.
2172    *
2173    * This overload requires that the Protocol template parameter satisfy the
2174    * AcceptableProtocol type requirements.
2175    *
2176    * @param context The I/O execution context object to be used for the newly
2177    * accepted socket.
2178    *
2179    * @param peer_endpoint An endpoint object into which the endpoint of the
2180    * remote peer will be written.
2181    *
2182    * @returns A socket object representing the newly accepted connection.
2183    *
2184    * @throws boost::system::system_error Thrown on failure.
2185    *
2186    * @par Example
2187    * @code
2188    * boost::asio::ip::tcp::acceptor acceptor(my_context);
2189    * ...
2190    * boost::asio::ip::tcp::endpoint endpoint;
2191    * boost::asio::ip::tcp::socket socket(
2192    *     acceptor.accept(my_context2, endpoint));
2193    * @endcode
2194    */
2195   template <typename ExecutionContext>
2196   typename Protocol::socket::template rebind_executor<
2197       typename ExecutionContext::executor_type>::other
accept(ExecutionContext & context,endpoint_type & peer_endpoint,typename constraint<is_convertible<ExecutionContext &,execution_context &>::value>::type=0)2198   accept(ExecutionContext& context, endpoint_type& peer_endpoint,
2199       typename constraint<
2200         is_convertible<ExecutionContext&, execution_context&>::value
2201       >::type = 0)
2202   {
2203     boost::system::error_code ec;
2204     typename Protocol::socket::template rebind_executor<
2205         typename ExecutionContext::executor_type>::other peer(context);
2206     impl_.get_service().accept(impl_.get_implementation(),
2207         peer, &peer_endpoint, ec);
2208     boost::asio::detail::throw_error(ec, "accept");
2209     return peer;
2210   }
2211 
2212   /// Accept a new connection.
2213   /**
2214    * This function is used to accept a new connection from a peer. The function
2215    * call will block until a new connection has been accepted successfully or
2216    * an error occurs.
2217    *
2218    * This overload requires that the Protocol template parameter satisfy the
2219    * AcceptableProtocol type requirements.
2220    *
2221    * @param ex The I/O executor object to be used for the newly accepted
2222    * socket.
2223    *
2224    * @param peer_endpoint An endpoint object into which the endpoint of the
2225    * remote peer will be written.
2226    *
2227    * @param ec Set to indicate what error occurred, if any.
2228    *
2229    * @returns On success, a socket object representing the newly accepted
2230    * connection. On error, a socket object where is_open() is false.
2231    *
2232    * @par Example
2233    * @code
2234    * boost::asio::ip::tcp::acceptor acceptor(my_context);
2235    * ...
2236    * boost::asio::ip::tcp::endpoint endpoint;
2237    * boost::asio::ip::tcp::socket socket(
2238    *     acceptor.accept(my_context2, endpoint, ec));
2239    * if (ec)
2240    * {
2241    *   // An error occurred.
2242    * }
2243    * @endcode
2244    */
2245   template <typename Executor1>
2246   typename Protocol::socket::template rebind_executor<Executor1>::other
accept(const executor_type & ex,endpoint_type & peer_endpoint,boost::system::error_code & ec,typename constraint<is_executor<Executor1>::value||execution::is_executor<Executor1>::value>::type=0)2247   accept(const executor_type& ex,
2248       endpoint_type& peer_endpoint, boost::system::error_code& ec,
2249       typename constraint<
2250         is_executor<Executor1>::value
2251           || execution::is_executor<Executor1>::value
2252       >::type = 0)
2253   {
2254     typename Protocol::socket::template
2255       rebind_executor<Executor1>::other peer(ex);
2256     impl_.get_service().accept(impl_.get_implementation(),
2257         peer, &peer_endpoint, ec);
2258     return peer;
2259   }
2260 
2261   /// Accept a new connection.
2262   /**
2263    * This function is used to accept a new connection from a peer. The function
2264    * call will block until a new connection has been accepted successfully or
2265    * an error occurs.
2266    *
2267    * This overload requires that the Protocol template parameter satisfy the
2268    * AcceptableProtocol type requirements.
2269    *
2270    * @param context The I/O execution context object to be used for the newly
2271    * accepted socket.
2272    *
2273    * @param peer_endpoint An endpoint object into which the endpoint of the
2274    * remote peer will be written.
2275    *
2276    * @param ec Set to indicate what error occurred, if any.
2277    *
2278    * @returns On success, a socket object representing the newly accepted
2279    * connection. On error, a socket object where is_open() is false.
2280    *
2281    * @par Example
2282    * @code
2283    * boost::asio::ip::tcp::acceptor acceptor(my_context);
2284    * ...
2285    * boost::asio::ip::tcp::endpoint endpoint;
2286    * boost::asio::ip::tcp::socket socket(
2287    *     acceptor.accept(my_context2, endpoint, ec));
2288    * if (ec)
2289    * {
2290    *   // An error occurred.
2291    * }
2292    * @endcode
2293    */
2294   template <typename ExecutionContext>
2295   typename Protocol::socket::template rebind_executor<
2296       typename ExecutionContext::executor_type>::other
accept(ExecutionContext & context,endpoint_type & peer_endpoint,boost::system::error_code & ec,typename constraint<is_convertible<ExecutionContext &,execution_context &>::value>::type=0)2297   accept(ExecutionContext& context,
2298       endpoint_type& peer_endpoint, boost::system::error_code& ec,
2299       typename constraint<
2300         is_convertible<ExecutionContext&, execution_context&>::value
2301       >::type = 0)
2302   {
2303     typename Protocol::socket::template rebind_executor<
2304         typename ExecutionContext::executor_type>::other peer(context);
2305     impl_.get_service().accept(impl_.get_implementation(),
2306         peer, &peer_endpoint, ec);
2307     return peer;
2308   }
2309 
2310   /// Start an asynchronous accept.
2311   /**
2312    * This function is used to asynchronously accept a new connection. The
2313    * function call always returns immediately.
2314    *
2315    * This overload requires that the Protocol template parameter satisfy the
2316    * AcceptableProtocol type requirements.
2317    *
2318    * @param ex The I/O executor object to be used for the newly accepted
2319    * socket.
2320    *
2321    * @param peer_endpoint An endpoint object into which the endpoint of the
2322    * remote peer will be written. Ownership of the peer_endpoint object is
2323    * retained by the caller, which must guarantee that it is valid until the
2324    * handler is called.
2325    *
2326    * @param handler The handler to be called when the accept operation
2327    * completes. Copies will be made of the handler as required. The function
2328    * signature of the handler must be:
2329    * @code void handler(
2330    *   const boost::system::error_code& error, // Result of operation.
2331    *   typename Protocol::socket::template rebind_executor<
2332    *     Executor1>::other peer // On success, the newly accepted socket.
2333    * ); @endcode
2334    * Regardless of whether the asynchronous operation completes immediately or
2335    * not, the handler will not be invoked from within this function. On
2336    * immediate completion, invocation of the handler will be performed in a
2337    * manner equivalent to using boost::asio::post().
2338    *
2339    * @par Example
2340    * @code
2341    * void accept_handler(const boost::system::error_code& error,
2342    *     boost::asio::ip::tcp::socket peer)
2343    * {
2344    *   if (!error)
2345    *   {
2346    *     // Accept succeeded.
2347    *   }
2348    * }
2349    *
2350    * ...
2351    *
2352    * boost::asio::ip::tcp::acceptor acceptor(my_context);
2353    * ...
2354    * boost::asio::ip::tcp::endpoint endpoint;
2355    * acceptor.async_accept(my_context2, endpoint, accept_handler);
2356    * @endcode
2357    *
2358    * @par Per-Operation Cancellation
2359    * On POSIX or Windows operating systems, this asynchronous operation supports
2360    * cancellation for the following boost::asio::cancellation_type values:
2361    *
2362    * @li @c cancellation_type::terminal
2363    *
2364    * @li @c cancellation_type::partial
2365    *
2366    * @li @c cancellation_type::total
2367    */
2368   template <typename Executor1,
2369       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
2370         typename Protocol::socket::template rebind_executor<
2371           Executor1>::other)) MoveAcceptHandler
2372             BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,void (boost::system::error_code,typename Protocol::socket::template rebind_executor<Executor1>::other))2373   BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,
2374       void (boost::system::error_code,
2375         typename Protocol::socket::template rebind_executor<
2376           Executor1>::other))
2377   async_accept(const Executor1& ex, endpoint_type& peer_endpoint,
2378       BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler
2379         BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
2380       typename constraint<
2381         is_executor<Executor1>::value
2382           || execution::is_executor<Executor1>::value
2383       >::type = 0)
2384   {
2385     typedef typename Protocol::socket::template rebind_executor<
2386       Executor1>::other other_socket_type;
2387 
2388     return async_initiate<MoveAcceptHandler,
2389       void (boost::system::error_code, other_socket_type)>(
2390         initiate_async_move_accept(this), handler,
2391         ex, &peer_endpoint,
2392         static_cast<other_socket_type*>(0));
2393   }
2394 
2395   /// Start an asynchronous accept.
2396   /**
2397    * This function is used to asynchronously accept a new connection. The
2398    * function call always returns immediately.
2399    *
2400    * This overload requires that the Protocol template parameter satisfy the
2401    * AcceptableProtocol type requirements.
2402    *
2403    * @param context The I/O execution context object to be used for the newly
2404    * accepted socket.
2405    *
2406    * @param peer_endpoint An endpoint object into which the endpoint of the
2407    * remote peer will be written. Ownership of the peer_endpoint object is
2408    * retained by the caller, which must guarantee that it is valid until the
2409    * handler is called.
2410    *
2411    * @param handler The handler to be called when the accept operation
2412    * completes. Copies will be made of the handler as required. The function
2413    * signature of the handler must be:
2414    * @code void handler(
2415    *   const boost::system::error_code& error, // Result of operation.
2416    *   typename Protocol::socket::template rebind_executor<
2417    *     typename ExecutionContext::executor_type>::other peer
2418    *       // On success, the newly accepted socket.
2419    * ); @endcode
2420    * Regardless of whether the asynchronous operation completes immediately or
2421    * not, the handler will not be invoked from within this function. On
2422    * immediate completion, invocation of the handler will be performed in a
2423    * manner equivalent to using boost::asio::post().
2424    *
2425    * @par Example
2426    * @code
2427    * void accept_handler(const boost::system::error_code& error,
2428    *     boost::asio::ip::tcp::socket peer)
2429    * {
2430    *   if (!error)
2431    *   {
2432    *     // Accept succeeded.
2433    *   }
2434    * }
2435    *
2436    * ...
2437    *
2438    * boost::asio::ip::tcp::acceptor acceptor(my_context);
2439    * ...
2440    * boost::asio::ip::tcp::endpoint endpoint;
2441    * acceptor.async_accept(my_context2, endpoint, accept_handler);
2442    * @endcode
2443    *
2444    * @par Per-Operation Cancellation
2445    * On POSIX or Windows operating systems, this asynchronous operation supports
2446    * cancellation for the following boost::asio::cancellation_type values:
2447    *
2448    * @li @c cancellation_type::terminal
2449    *
2450    * @li @c cancellation_type::partial
2451    *
2452    * @li @c cancellation_type::total
2453    */
2454   template <typename ExecutionContext,
2455       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
2456         typename Protocol::socket::template rebind_executor<
2457           typename ExecutionContext::executor_type>::other)) MoveAcceptHandler
2458             BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,void (boost::system::error_code,typename Protocol::socket::template rebind_executor<typename ExecutionContext::executor_type>::other))2459   BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,
2460       void (boost::system::error_code,
2461         typename Protocol::socket::template rebind_executor<
2462           typename ExecutionContext::executor_type>::other))
2463   async_accept(ExecutionContext& context,
2464       endpoint_type& peer_endpoint,
2465       BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler
2466         BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
2467       typename constraint<
2468         is_convertible<ExecutionContext&, execution_context&>::value
2469       >::type = 0)
2470   {
2471     typedef typename Protocol::socket::template rebind_executor<
2472       typename ExecutionContext::executor_type>::other other_socket_type;
2473 
2474     return async_initiate<MoveAcceptHandler,
2475       void (boost::system::error_code, other_socket_type)>(
2476         initiate_async_move_accept(this), handler,
2477         context.get_executor(), &peer_endpoint,
2478         static_cast<other_socket_type*>(0));
2479   }
2480 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
2481 
2482 private:
2483   // Disallow copying and assignment.
2484   basic_socket_acceptor(const basic_socket_acceptor&) BOOST_ASIO_DELETED;
2485   basic_socket_acceptor& operator=(
2486       const basic_socket_acceptor&) BOOST_ASIO_DELETED;
2487 
2488   class initiate_async_wait
2489   {
2490   public:
2491     typedef Executor executor_type;
2492 
initiate_async_wait(basic_socket_acceptor * self)2493     explicit initiate_async_wait(basic_socket_acceptor* self)
2494       : self_(self)
2495     {
2496     }
2497 
get_executor() const2498     executor_type get_executor() const BOOST_ASIO_NOEXCEPT
2499     {
2500       return self_->get_executor();
2501     }
2502 
2503     template <typename WaitHandler>
operator ()(BOOST_ASIO_MOVE_ARG (WaitHandler)handler,wait_type w) const2504     void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, wait_type w) const
2505     {
2506       // If you get an error on the following line it means that your handler
2507       // does not meet the documented type requirements for a WaitHandler.
2508       BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
2509 
2510       detail::non_const_lvalue<WaitHandler> handler2(handler);
2511       self_->impl_.get_service().async_wait(
2512           self_->impl_.get_implementation(), w,
2513           handler2.value, self_->impl_.get_executor());
2514     }
2515 
2516   private:
2517     basic_socket_acceptor* self_;
2518   };
2519 
2520   class initiate_async_accept
2521   {
2522   public:
2523     typedef Executor executor_type;
2524 
initiate_async_accept(basic_socket_acceptor * self)2525     explicit initiate_async_accept(basic_socket_acceptor* self)
2526       : self_(self)
2527     {
2528     }
2529 
get_executor() const2530     executor_type get_executor() const BOOST_ASIO_NOEXCEPT
2531     {
2532       return self_->get_executor();
2533     }
2534 
2535     template <typename AcceptHandler, typename Protocol1, typename Executor1>
operator ()(BOOST_ASIO_MOVE_ARG (AcceptHandler)handler,basic_socket<Protocol1,Executor1> * peer,endpoint_type * peer_endpoint) const2536     void operator()(BOOST_ASIO_MOVE_ARG(AcceptHandler) handler,
2537         basic_socket<Protocol1, Executor1>* peer,
2538         endpoint_type* peer_endpoint) const
2539     {
2540       // If you get an error on the following line it means that your handler
2541       // does not meet the documented type requirements for a AcceptHandler.
2542       BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check;
2543 
2544       detail::non_const_lvalue<AcceptHandler> handler2(handler);
2545       self_->impl_.get_service().async_accept(
2546           self_->impl_.get_implementation(), *peer, peer_endpoint,
2547           handler2.value, self_->impl_.get_executor());
2548     }
2549 
2550   private:
2551     basic_socket_acceptor* self_;
2552   };
2553 
2554   class initiate_async_move_accept
2555   {
2556   public:
2557     typedef Executor executor_type;
2558 
initiate_async_move_accept(basic_socket_acceptor * self)2559     explicit initiate_async_move_accept(basic_socket_acceptor* self)
2560       : self_(self)
2561     {
2562     }
2563 
get_executor() const2564     executor_type get_executor() const BOOST_ASIO_NOEXCEPT
2565     {
2566       return self_->get_executor();
2567     }
2568 
2569     template <typename MoveAcceptHandler, typename Executor1, typename Socket>
operator ()(BOOST_ASIO_MOVE_ARG (MoveAcceptHandler)handler,const Executor1 & peer_ex,endpoint_type * peer_endpoint,Socket *) const2570     void operator()(BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler,
2571         const Executor1& peer_ex, endpoint_type* peer_endpoint, Socket*) const
2572     {
2573       // If you get an error on the following line it means that your handler
2574       // does not meet the documented type requirements for a MoveAcceptHandler.
2575       BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK(
2576           MoveAcceptHandler, handler, Socket) type_check;
2577 
2578       detail::non_const_lvalue<MoveAcceptHandler> handler2(handler);
2579       self_->impl_.get_service().async_move_accept(
2580           self_->impl_.get_implementation(), peer_ex, peer_endpoint,
2581           handler2.value, self_->impl_.get_executor());
2582     }
2583 
2584   private:
2585     basic_socket_acceptor* self_;
2586   };
2587 
2588 #if defined(BOOST_ASIO_WINDOWS_RUNTIME)
2589   detail::io_object_impl<
2590     detail::null_socket_service<Protocol>, Executor> impl_;
2591 #elif defined(BOOST_ASIO_HAS_IOCP)
2592   detail::io_object_impl<
2593     detail::win_iocp_socket_service<Protocol>, Executor> impl_;
2594 #elif defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
2595   detail::io_object_impl<
2596     detail::io_uring_socket_service<Protocol>, Executor> impl_;
2597 #else
2598   detail::io_object_impl<
2599     detail::reactive_socket_service<Protocol>, Executor> impl_;
2600 #endif
2601 };
2602 
2603 } // namespace asio
2604 } // namespace boost
2605 
2606 #include <boost/asio/detail/pop_options.hpp>
2607 
2608 #endif // BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_HPP
2609