1 //
2 // basic_socket_acceptor.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 //
10 
11 #ifndef ASIO_BASIC_SOCKET_ACCEPTOR_HPP
12 #define ASIO_BASIC_SOCKET_ACCEPTOR_HPP
13 
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17 
18 #include "asio/detail/config.hpp"
19 #include "asio/basic_io_object.hpp"
20 #include "asio/basic_socket.hpp"
21 #include "asio/detail/handler_type_requirements.hpp"
22 #include "asio/detail/throw_error.hpp"
23 #include "asio/detail/type_traits.hpp"
24 #include "asio/error.hpp"
25 #include "asio/socket_base.hpp"
26 
27 #if defined(ASIO_HAS_MOVE)
28 # include <utility>
29 #endif // defined(ASIO_HAS_MOVE)
30 
31 #if defined(ASIO_ENABLE_OLD_SERVICES)
32 # include "asio/socket_acceptor_service.hpp"
33 #else // defined(ASIO_ENABLE_OLD_SERVICES)
34 # if defined(ASIO_WINDOWS_RUNTIME)
35 #  include "asio/detail/null_socket_service.hpp"
36 #  define ASIO_SVC_T detail::null_socket_service<Protocol>
37 # elif defined(ASIO_HAS_IOCP)
38 #  include "asio/detail/win_iocp_socket_service.hpp"
39 #  define ASIO_SVC_T detail::win_iocp_socket_service<Protocol>
40 # else
41 #  include "asio/detail/reactive_socket_service.hpp"
42 #  define ASIO_SVC_T detail::reactive_socket_service<Protocol>
43 # endif
44 #endif // defined(ASIO_ENABLE_OLD_SERVICES)
45 
46 #include "asio/detail/push_options.hpp"
47 
48 namespace asio {
49 
50 /// Provides the ability to accept new connections.
51 /**
52  * The basic_socket_acceptor class template is used for accepting new socket
53  * connections.
54  *
55  * @par Thread Safety
56  * @e Distinct @e objects: Safe.@n
57  * @e Shared @e objects: Unsafe.
58  *
59  * @par Example
60  * Opening a socket acceptor with the SO_REUSEADDR option enabled:
61  * @code
62  * asio::ip::tcp::acceptor acceptor(io_context);
63  * asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), port);
64  * acceptor.open(endpoint.protocol());
65  * acceptor.set_option(asio::ip::tcp::acceptor::reuse_address(true));
66  * acceptor.bind(endpoint);
67  * acceptor.listen();
68  * @endcode
69  */
70 template <typename Protocol
71     ASIO_SVC_TPARAM_DEF1(= socket_acceptor_service<Protocol>)>
72 class basic_socket_acceptor
73   : ASIO_SVC_ACCESS basic_io_object<ASIO_SVC_T>,
74     public socket_base
75 {
76 public:
77   /// The type of the executor associated with the object.
78   typedef io_context::executor_type executor_type;
79 
80   /// The native representation of an acceptor.
81 #if defined(GENERATING_DOCUMENTATION)
82   typedef implementation_defined native_handle_type;
83 #else
84   typedef typename ASIO_SVC_T::native_handle_type native_handle_type;
85 #endif
86 
87   /// The protocol type.
88   typedef Protocol protocol_type;
89 
90   /// The endpoint type.
91   typedef typename Protocol::endpoint endpoint_type;
92 
93   /// Construct an acceptor without opening it.
94   /**
95    * This constructor creates an acceptor without opening it to listen for new
96    * connections. The open() function must be called before the acceptor can
97    * accept new socket connections.
98    *
99    * @param io_context The io_context object that the acceptor will use to
100    * dispatch handlers for any asynchronous operations performed on the
101    * acceptor.
102    */
basic_socket_acceptor(asio::io_context & io_context)103   explicit basic_socket_acceptor(asio::io_context& io_context)
104     : basic_io_object<ASIO_SVC_T>(io_context)
105   {
106   }
107 
108   /// Construct an open acceptor.
109   /**
110    * This constructor creates an acceptor and automatically opens it.
111    *
112    * @param io_context The io_context object that the acceptor will use to
113    * dispatch handlers for any asynchronous operations performed on the
114    * acceptor.
115    *
116    * @param protocol An object specifying protocol parameters to be used.
117    *
118    * @throws asio::system_error Thrown on failure.
119    */
basic_socket_acceptor(asio::io_context & io_context,const protocol_type & protocol)120   basic_socket_acceptor(asio::io_context& io_context,
121       const protocol_type& protocol)
122     : basic_io_object<ASIO_SVC_T>(io_context)
123   {
124     asio::error_code ec;
125     this->get_service().open(this->get_implementation(), protocol, ec);
126     asio::detail::throw_error(ec, "open");
127   }
128 
129   /// Construct an acceptor opened on the given endpoint.
130   /**
131    * This constructor creates an acceptor and automatically opens it to listen
132    * for new connections on the specified endpoint.
133    *
134    * @param io_context The io_context object that the acceptor will use to
135    * dispatch handlers for any asynchronous operations performed on the
136    * acceptor.
137    *
138    * @param endpoint An endpoint on the local machine on which the acceptor
139    * will listen for new connections.
140    *
141    * @param reuse_addr Whether the constructor should set the socket option
142    * socket_base::reuse_address.
143    *
144    * @throws asio::system_error Thrown on failure.
145    *
146    * @note This constructor is equivalent to the following code:
147    * @code
148    * basic_socket_acceptor<Protocol> acceptor(io_context);
149    * acceptor.open(endpoint.protocol());
150    * if (reuse_addr)
151    *   acceptor.set_option(socket_base::reuse_address(true));
152    * acceptor.bind(endpoint);
153    * acceptor.listen(listen_backlog);
154    * @endcode
155    */
basic_socket_acceptor(asio::io_context & io_context,const endpoint_type & endpoint,bool reuse_addr=true)156   basic_socket_acceptor(asio::io_context& io_context,
157       const endpoint_type& endpoint, bool reuse_addr = true)
158     : basic_io_object<ASIO_SVC_T>(io_context)
159   {
160     asio::error_code ec;
161     const protocol_type protocol = endpoint.protocol();
162     this->get_service().open(this->get_implementation(), protocol, ec);
163     asio::detail::throw_error(ec, "open");
164     if (reuse_addr)
165     {
166       this->get_service().set_option(this->get_implementation(),
167           socket_base::reuse_address(true), ec);
168       asio::detail::throw_error(ec, "set_option");
169     }
170     this->get_service().bind(this->get_implementation(), endpoint, ec);
171     asio::detail::throw_error(ec, "bind");
172     this->get_service().listen(this->get_implementation(),
173         socket_base::max_listen_connections, ec);
174     asio::detail::throw_error(ec, "listen");
175   }
176 
177   /// Construct a basic_socket_acceptor on an existing native acceptor.
178   /**
179    * This constructor creates an acceptor object to hold an existing native
180    * acceptor.
181    *
182    * @param io_context The io_context object that the acceptor will use to
183    * dispatch handlers for any asynchronous operations performed on the
184    * acceptor.
185    *
186    * @param protocol An object specifying protocol parameters to be used.
187    *
188    * @param native_acceptor A native acceptor.
189    *
190    * @throws asio::system_error Thrown on failure.
191    */
basic_socket_acceptor(asio::io_context & io_context,const protocol_type & protocol,const native_handle_type & native_acceptor)192   basic_socket_acceptor(asio::io_context& io_context,
193       const protocol_type& protocol, const native_handle_type& native_acceptor)
194     : basic_io_object<ASIO_SVC_T>(io_context)
195   {
196     asio::error_code ec;
197     this->get_service().assign(this->get_implementation(),
198         protocol, native_acceptor, ec);
199     asio::detail::throw_error(ec, "assign");
200   }
201 
202 #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
203   /// Move-construct a basic_socket_acceptor from another.
204   /**
205    * This constructor moves an acceptor from one object to another.
206    *
207    * @param other The other basic_socket_acceptor object from which the move
208    * will occur.
209    *
210    * @note Following the move, the moved-from object is in the same state as if
211    * constructed using the @c basic_socket_acceptor(io_context&) constructor.
212    */
basic_socket_acceptor(basic_socket_acceptor && other)213   basic_socket_acceptor(basic_socket_acceptor&& other)
214     : basic_io_object<ASIO_SVC_T>(std::move(other))
215   {
216   }
217 
218   /// Move-assign a basic_socket_acceptor from another.
219   /**
220    * This assignment operator moves an acceptor from one object to another.
221    *
222    * @param other The other basic_socket_acceptor object from which the move
223    * will occur.
224    *
225    * @note Following the move, the moved-from object is in the same state as if
226    * constructed using the @c basic_socket_acceptor(io_context&) constructor.
227    */
operator =(basic_socket_acceptor && other)228   basic_socket_acceptor& operator=(basic_socket_acceptor&& other)
229   {
230     basic_io_object<ASIO_SVC_T>::operator=(std::move(other));
231     return *this;
232   }
233 
234   // All socket acceptors have access to each other's implementations.
235   template <typename Protocol1 ASIO_SVC_TPARAM1>
236   friend class basic_socket_acceptor;
237 
238   /// Move-construct a basic_socket_acceptor from an acceptor of another
239   /// protocol type.
240   /**
241    * This constructor moves an acceptor from one object to another.
242    *
243    * @param other The other basic_socket_acceptor object from which the move
244    * will occur.
245    *
246    * @note Following the move, the moved-from object is in the same state as if
247    * constructed using the @c basic_socket(io_context&) constructor.
248    */
249   template <typename Protocol1 ASIO_SVC_TPARAM1>
basic_socket_acceptor(basic_socket_acceptor<Protocol1 ASIO_SVC_TARG1> && other,typename enable_if<is_convertible<Protocol1,Protocol>::value>::type * =0)250   basic_socket_acceptor(
251       basic_socket_acceptor<Protocol1 ASIO_SVC_TARG1>&& other,
252       typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
253     : basic_io_object<ASIO_SVC_T>(
254         other.get_service(), other.get_implementation())
255   {
256   }
257 
258   /// Move-assign a basic_socket_acceptor from an acceptor of another protocol
259   /// type.
260   /**
261    * This assignment operator moves an acceptor from one object to another.
262    *
263    * @param other The other basic_socket_acceptor object from which the move
264    * will occur.
265    *
266    * @note Following the move, the moved-from object is in the same state as if
267    * constructed using the @c basic_socket(io_context&) constructor.
268    */
269   template <typename Protocol1 ASIO_SVC_TPARAM1>
270   typename enable_if<is_convertible<Protocol1, Protocol>::value,
operator =(basic_socket_acceptor<Protocol1 ASIO_SVC_TARG1> && other)271       basic_socket_acceptor>::type& operator=(
272         basic_socket_acceptor<Protocol1 ASIO_SVC_TARG1>&& other)
273   {
274     basic_socket_acceptor tmp(std::move(other));
275     basic_io_object<ASIO_SVC_T>::operator=(std::move(tmp));
276     return *this;
277   }
278 #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
279 
280   /// Destroys the acceptor.
281   /**
282    * This function destroys the acceptor, cancelling any outstanding
283    * asynchronous operations associated with the acceptor as if by calling
284    * @c cancel.
285    */
~basic_socket_acceptor()286   ~basic_socket_acceptor()
287   {
288   }
289 
290 #if defined(ASIO_ENABLE_OLD_SERVICES)
291   // These functions are provided by basic_io_object<>.
292 #else // defined(ASIO_ENABLE_OLD_SERVICES)
293 #if !defined(ASIO_NO_DEPRECATED)
294   /// (Deprecated: Use get_executor().) Get the io_context associated with the
295   /// object.
296   /**
297    * This function may be used to obtain the io_context object that the I/O
298    * object uses to dispatch handlers for asynchronous operations.
299    *
300    * @return A reference to the io_context object that the I/O object will use
301    * to dispatch handlers. Ownership is not transferred to the caller.
302    */
get_io_context()303   asio::io_context& get_io_context()
304   {
305     return basic_io_object<ASIO_SVC_T>::get_io_context();
306   }
307 
308   /// (Deprecated: Use get_executor().) Get the io_context associated with the
309   /// object.
310   /**
311    * This function may be used to obtain the io_context object that the I/O
312    * object uses to dispatch handlers for asynchronous operations.
313    *
314    * @return A reference to the io_context object that the I/O object will use
315    * to dispatch handlers. Ownership is not transferred to the caller.
316    */
get_io_service()317   asio::io_context& get_io_service()
318   {
319     return basic_io_object<ASIO_SVC_T>::get_io_service();
320   }
321 #endif // !defined(ASIO_NO_DEPRECATED)
322 
323   /// Get the executor associated with the object.
get_executor()324   executor_type get_executor() ASIO_NOEXCEPT
325   {
326     return basic_io_object<ASIO_SVC_T>::get_executor();
327   }
328 #endif // defined(ASIO_ENABLE_OLD_SERVICES)
329 
330   /// Open the acceptor using the specified protocol.
331   /**
332    * This function opens the socket acceptor so that it will use the specified
333    * protocol.
334    *
335    * @param protocol An object specifying which protocol is to be used.
336    *
337    * @throws asio::system_error Thrown on failure.
338    *
339    * @par Example
340    * @code
341    * asio::ip::tcp::acceptor acceptor(io_context);
342    * acceptor.open(asio::ip::tcp::v4());
343    * @endcode
344    */
open(const protocol_type & protocol=protocol_type ())345   void open(const protocol_type& protocol = protocol_type())
346   {
347     asio::error_code ec;
348     this->get_service().open(this->get_implementation(), protocol, ec);
349     asio::detail::throw_error(ec, "open");
350   }
351 
352   /// Open the acceptor using the specified protocol.
353   /**
354    * This function opens the socket acceptor so that it will use the specified
355    * protocol.
356    *
357    * @param protocol An object specifying which protocol is to be used.
358    *
359    * @param ec Set to indicate what error occurred, if any.
360    *
361    * @par Example
362    * @code
363    * asio::ip::tcp::acceptor acceptor(io_context);
364    * asio::error_code ec;
365    * acceptor.open(asio::ip::tcp::v4(), ec);
366    * if (ec)
367    * {
368    *   // An error occurred.
369    * }
370    * @endcode
371    */
open(const protocol_type & protocol,asio::error_code & ec)372   ASIO_SYNC_OP_VOID open(const protocol_type& protocol,
373       asio::error_code& ec)
374   {
375     this->get_service().open(this->get_implementation(), protocol, ec);
376     ASIO_SYNC_OP_VOID_RETURN(ec);
377   }
378 
379   /// Assigns an existing native acceptor to the acceptor.
380   /*
381    * This function opens the acceptor to hold an existing native acceptor.
382    *
383    * @param protocol An object specifying which protocol is to be used.
384    *
385    * @param native_acceptor A native acceptor.
386    *
387    * @throws asio::system_error Thrown on failure.
388    */
assign(const protocol_type & protocol,const native_handle_type & native_acceptor)389   void assign(const protocol_type& protocol,
390       const native_handle_type& native_acceptor)
391   {
392     asio::error_code ec;
393     this->get_service().assign(this->get_implementation(),
394         protocol, native_acceptor, ec);
395     asio::detail::throw_error(ec, "assign");
396   }
397 
398   /// Assigns an existing native acceptor to the acceptor.
399   /*
400    * This function opens the acceptor to hold an existing native acceptor.
401    *
402    * @param protocol An object specifying which protocol is to be used.
403    *
404    * @param native_acceptor A native acceptor.
405    *
406    * @param ec Set to indicate what error occurred, if any.
407    */
assign(const protocol_type & protocol,const native_handle_type & native_acceptor,asio::error_code & ec)408   ASIO_SYNC_OP_VOID assign(const protocol_type& protocol,
409       const native_handle_type& native_acceptor, asio::error_code& ec)
410   {
411     this->get_service().assign(this->get_implementation(),
412         protocol, native_acceptor, ec);
413     ASIO_SYNC_OP_VOID_RETURN(ec);
414   }
415 
416   /// Determine whether the acceptor is open.
is_open() const417   bool is_open() const
418   {
419     return this->get_service().is_open(this->get_implementation());
420   }
421 
422   /// Bind the acceptor to the given local endpoint.
423   /**
424    * This function binds the socket acceptor to the specified endpoint on the
425    * local machine.
426    *
427    * @param endpoint An endpoint on the local machine to which the socket
428    * acceptor will be bound.
429    *
430    * @throws asio::system_error Thrown on failure.
431    *
432    * @par Example
433    * @code
434    * asio::ip::tcp::acceptor acceptor(io_context);
435    * asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), 12345);
436    * acceptor.open(endpoint.protocol());
437    * acceptor.bind(endpoint);
438    * @endcode
439    */
bind(const endpoint_type & endpoint)440   void bind(const endpoint_type& endpoint)
441   {
442     asio::error_code ec;
443     this->get_service().bind(this->get_implementation(), endpoint, ec);
444     asio::detail::throw_error(ec, "bind");
445   }
446 
447   /// Bind the acceptor to the given local endpoint.
448   /**
449    * This function binds the socket acceptor to the specified endpoint on the
450    * local machine.
451    *
452    * @param endpoint An endpoint on the local machine to which the socket
453    * acceptor will be bound.
454    *
455    * @param ec Set to indicate what error occurred, if any.
456    *
457    * @par Example
458    * @code
459    * asio::ip::tcp::acceptor acceptor(io_context);
460    * asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), 12345);
461    * acceptor.open(endpoint.protocol());
462    * asio::error_code ec;
463    * acceptor.bind(endpoint, ec);
464    * if (ec)
465    * {
466    *   // An error occurred.
467    * }
468    * @endcode
469    */
bind(const endpoint_type & endpoint,asio::error_code & ec)470   ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint,
471       asio::error_code& ec)
472   {
473     this->get_service().bind(this->get_implementation(), endpoint, ec);
474     ASIO_SYNC_OP_VOID_RETURN(ec);
475   }
476 
477   /// Place the acceptor into the state where it will listen for new
478   /// connections.
479   /**
480    * This function puts the socket acceptor into the state where it may accept
481    * new connections.
482    *
483    * @param backlog The maximum length of the queue of pending connections.
484    *
485    * @throws asio::system_error Thrown on failure.
486    */
listen(int backlog=socket_base::max_listen_connections)487   void listen(int backlog = socket_base::max_listen_connections)
488   {
489     asio::error_code ec;
490     this->get_service().listen(this->get_implementation(), backlog, ec);
491     asio::detail::throw_error(ec, "listen");
492   }
493 
494   /// Place the acceptor into the state where it will listen for new
495   /// connections.
496   /**
497    * This function puts the socket acceptor into the state where it may accept
498    * new connections.
499    *
500    * @param backlog The maximum length of the queue of pending connections.
501    *
502    * @param ec Set to indicate what error occurred, if any.
503    *
504    * @par Example
505    * @code
506    * asio::ip::tcp::acceptor acceptor(io_context);
507    * ...
508    * asio::error_code ec;
509    * acceptor.listen(asio::socket_base::max_listen_connections, ec);
510    * if (ec)
511    * {
512    *   // An error occurred.
513    * }
514    * @endcode
515    */
listen(int backlog,asio::error_code & ec)516   ASIO_SYNC_OP_VOID listen(int backlog, asio::error_code& ec)
517   {
518     this->get_service().listen(this->get_implementation(), backlog, ec);
519     ASIO_SYNC_OP_VOID_RETURN(ec);
520   }
521 
522   /// Close the acceptor.
523   /**
524    * This function is used to close the acceptor. Any asynchronous accept
525    * operations will be cancelled immediately.
526    *
527    * A subsequent call to open() is required before the acceptor can again be
528    * used to again perform socket accept operations.
529    *
530    * @throws asio::system_error Thrown on failure.
531    */
close()532   void close()
533   {
534     asio::error_code ec;
535     this->get_service().close(this->get_implementation(), ec);
536     asio::detail::throw_error(ec, "close");
537   }
538 
539   /// Close the acceptor.
540   /**
541    * This function is used to close the acceptor. Any asynchronous accept
542    * operations will be cancelled immediately.
543    *
544    * A subsequent call to open() is required before the acceptor can again be
545    * used to again perform socket accept operations.
546    *
547    * @param ec Set to indicate what error occurred, if any.
548    *
549    * @par Example
550    * @code
551    * asio::ip::tcp::acceptor acceptor(io_context);
552    * ...
553    * asio::error_code ec;
554    * acceptor.close(ec);
555    * if (ec)
556    * {
557    *   // An error occurred.
558    * }
559    * @endcode
560    */
close(asio::error_code & ec)561   ASIO_SYNC_OP_VOID close(asio::error_code& ec)
562   {
563     this->get_service().close(this->get_implementation(), ec);
564     ASIO_SYNC_OP_VOID_RETURN(ec);
565   }
566 
567   /// Release ownership of the underlying native acceptor.
568   /**
569    * This function causes all outstanding asynchronous accept operations to
570    * finish immediately, and the handlers for cancelled operations will be
571    * passed the asio::error::operation_aborted error. Ownership of the
572    * native acceptor is then transferred to the caller.
573    *
574    * @throws asio::system_error Thrown on failure.
575    *
576    * @note This function is unsupported on Windows versions prior to Windows
577    * 8.1, and will fail with asio::error::operation_not_supported on
578    * these platforms.
579    */
580 #if defined(ASIO_MSVC) && (ASIO_MSVC >= 1400) \
581   && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
582   __declspec(deprecated("This function always fails with "
583         "operation_not_supported when used on Windows versions "
584         "prior to Windows 8.1."))
585 #endif
release()586   native_handle_type release()
587   {
588     asio::error_code ec;
589     native_handle_type s = this->get_service().release(
590         this->get_implementation(), ec);
591     asio::detail::throw_error(ec, "release");
592     return s;
593   }
594 
595   /// Release ownership of the underlying native acceptor.
596   /**
597    * This function causes all outstanding asynchronous accept operations to
598    * finish immediately, and the handlers for cancelled operations will be
599    * passed the asio::error::operation_aborted error. Ownership of the
600    * native acceptor is then transferred to the caller.
601    *
602    * @param ec Set to indicate what error occurred, if any.
603    *
604    * @note This function is unsupported on Windows versions prior to Windows
605    * 8.1, and will fail with asio::error::operation_not_supported on
606    * these platforms.
607    */
608 #if defined(ASIO_MSVC) && (ASIO_MSVC >= 1400) \
609   && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
610   __declspec(deprecated("This function always fails with "
611         "operation_not_supported when used on Windows versions "
612         "prior to Windows 8.1."))
613 #endif
release(asio::error_code & ec)614   native_handle_type release(asio::error_code& ec)
615   {
616     return this->get_service().release(this->get_implementation(), ec);
617   }
618 
619   /// Get the native acceptor representation.
620   /**
621    * This function may be used to obtain the underlying representation of the
622    * acceptor. This is intended to allow access to native acceptor functionality
623    * that is not otherwise provided.
624    */
native_handle()625   native_handle_type native_handle()
626   {
627     return this->get_service().native_handle(this->get_implementation());
628   }
629 
630   /// Cancel all asynchronous operations associated with the acceptor.
631   /**
632    * This function causes all outstanding asynchronous connect, send and receive
633    * operations to finish immediately, and the handlers for cancelled operations
634    * will be passed the asio::error::operation_aborted error.
635    *
636    * @throws asio::system_error Thrown on failure.
637    */
cancel()638   void cancel()
639   {
640     asio::error_code ec;
641     this->get_service().cancel(this->get_implementation(), ec);
642     asio::detail::throw_error(ec, "cancel");
643   }
644 
645   /// Cancel all asynchronous operations associated with the acceptor.
646   /**
647    * This function causes all outstanding asynchronous connect, send and receive
648    * operations to finish immediately, and the handlers for cancelled operations
649    * will be passed the asio::error::operation_aborted error.
650    *
651    * @param ec Set to indicate what error occurred, if any.
652    */
cancel(asio::error_code & ec)653   ASIO_SYNC_OP_VOID cancel(asio::error_code& ec)
654   {
655     this->get_service().cancel(this->get_implementation(), ec);
656     ASIO_SYNC_OP_VOID_RETURN(ec);
657   }
658 
659   /// Set an option on the acceptor.
660   /**
661    * This function is used to set an option on the acceptor.
662    *
663    * @param option The new option value to be set on the acceptor.
664    *
665    * @throws asio::system_error Thrown on failure.
666    *
667    * @sa SettableSocketOption @n
668    * asio::socket_base::reuse_address
669    * asio::socket_base::enable_connection_aborted
670    *
671    * @par Example
672    * Setting the SOL_SOCKET/SO_REUSEADDR option:
673    * @code
674    * asio::ip::tcp::acceptor acceptor(io_context);
675    * ...
676    * asio::ip::tcp::acceptor::reuse_address option(true);
677    * acceptor.set_option(option);
678    * @endcode
679    */
680   template <typename SettableSocketOption>
set_option(const SettableSocketOption & option)681   void set_option(const SettableSocketOption& option)
682   {
683     asio::error_code ec;
684     this->get_service().set_option(this->get_implementation(), option, ec);
685     asio::detail::throw_error(ec, "set_option");
686   }
687 
688   /// Set an option on the acceptor.
689   /**
690    * This function is used to set an option on the acceptor.
691    *
692    * @param option The new option value to be set on the acceptor.
693    *
694    * @param ec Set to indicate what error occurred, if any.
695    *
696    * @sa SettableSocketOption @n
697    * asio::socket_base::reuse_address
698    * asio::socket_base::enable_connection_aborted
699    *
700    * @par Example
701    * Setting the SOL_SOCKET/SO_REUSEADDR option:
702    * @code
703    * asio::ip::tcp::acceptor acceptor(io_context);
704    * ...
705    * asio::ip::tcp::acceptor::reuse_address option(true);
706    * asio::error_code ec;
707    * acceptor.set_option(option, ec);
708    * if (ec)
709    * {
710    *   // An error occurred.
711    * }
712    * @endcode
713    */
714   template <typename SettableSocketOption>
set_option(const SettableSocketOption & option,asio::error_code & ec)715   ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option,
716       asio::error_code& ec)
717   {
718     this->get_service().set_option(this->get_implementation(), option, ec);
719     ASIO_SYNC_OP_VOID_RETURN(ec);
720   }
721 
722   /// Get an option from the acceptor.
723   /**
724    * This function is used to get the current value of an option on the
725    * acceptor.
726    *
727    * @param option The option value to be obtained from the acceptor.
728    *
729    * @throws asio::system_error Thrown on failure.
730    *
731    * @sa GettableSocketOption @n
732    * asio::socket_base::reuse_address
733    *
734    * @par Example
735    * Getting the value of the SOL_SOCKET/SO_REUSEADDR option:
736    * @code
737    * asio::ip::tcp::acceptor acceptor(io_context);
738    * ...
739    * asio::ip::tcp::acceptor::reuse_address option;
740    * acceptor.get_option(option);
741    * bool is_set = option.get();
742    * @endcode
743    */
744   template <typename GettableSocketOption>
get_option(GettableSocketOption & option)745   void get_option(GettableSocketOption& option)
746   {
747     asio::error_code ec;
748     this->get_service().get_option(this->get_implementation(), option, ec);
749     asio::detail::throw_error(ec, "get_option");
750   }
751 
752   /// Get an option from the acceptor.
753   /**
754    * This function is used to get the current value of an option on the
755    * acceptor.
756    *
757    * @param option The option value to be obtained from the acceptor.
758    *
759    * @param ec Set to indicate what error occurred, if any.
760    *
761    * @sa GettableSocketOption @n
762    * asio::socket_base::reuse_address
763    *
764    * @par Example
765    * Getting the value of the SOL_SOCKET/SO_REUSEADDR option:
766    * @code
767    * asio::ip::tcp::acceptor acceptor(io_context);
768    * ...
769    * asio::ip::tcp::acceptor::reuse_address option;
770    * asio::error_code ec;
771    * acceptor.get_option(option, ec);
772    * if (ec)
773    * {
774    *   // An error occurred.
775    * }
776    * bool is_set = option.get();
777    * @endcode
778    */
779   template <typename GettableSocketOption>
get_option(GettableSocketOption & option,asio::error_code & ec)780   ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option,
781       asio::error_code& ec)
782   {
783     this->get_service().get_option(this->get_implementation(), option, ec);
784     ASIO_SYNC_OP_VOID_RETURN(ec);
785   }
786 
787   /// Perform an IO control command on the acceptor.
788   /**
789    * This function is used to execute an IO control command on the acceptor.
790    *
791    * @param command The IO control command to be performed on the acceptor.
792    *
793    * @throws asio::system_error Thrown on failure.
794    *
795    * @sa IoControlCommand @n
796    * asio::socket_base::non_blocking_io
797    *
798    * @par Example
799    * Getting the number of bytes ready to read:
800    * @code
801    * asio::ip::tcp::acceptor acceptor(io_context);
802    * ...
803    * asio::ip::tcp::acceptor::non_blocking_io command(true);
804    * socket.io_control(command);
805    * @endcode
806    */
807   template <typename IoControlCommand>
io_control(IoControlCommand & command)808   void io_control(IoControlCommand& command)
809   {
810     asio::error_code ec;
811     this->get_service().io_control(this->get_implementation(), command, ec);
812     asio::detail::throw_error(ec, "io_control");
813   }
814 
815   /// Perform an IO control command on the acceptor.
816   /**
817    * This function is used to execute an IO control command on the acceptor.
818    *
819    * @param command The IO control command to be performed on the acceptor.
820    *
821    * @param ec Set to indicate what error occurred, if any.
822    *
823    * @sa IoControlCommand @n
824    * asio::socket_base::non_blocking_io
825    *
826    * @par Example
827    * Getting the number of bytes ready to read:
828    * @code
829    * asio::ip::tcp::acceptor acceptor(io_context);
830    * ...
831    * asio::ip::tcp::acceptor::non_blocking_io command(true);
832    * asio::error_code ec;
833    * socket.io_control(command, ec);
834    * if (ec)
835    * {
836    *   // An error occurred.
837    * }
838    * @endcode
839    */
840   template <typename IoControlCommand>
io_control(IoControlCommand & command,asio::error_code & ec)841   ASIO_SYNC_OP_VOID io_control(IoControlCommand& command,
842       asio::error_code& ec)
843   {
844     this->get_service().io_control(this->get_implementation(), command, ec);
845     ASIO_SYNC_OP_VOID_RETURN(ec);
846   }
847 
848   /// Gets the non-blocking mode of the acceptor.
849   /**
850    * @returns @c true if the acceptor's synchronous operations will fail with
851    * asio::error::would_block if they are unable to perform the requested
852    * operation immediately. If @c false, synchronous operations will block
853    * until complete.
854    *
855    * @note The non-blocking mode has no effect on the behaviour of asynchronous
856    * operations. Asynchronous operations will never fail with the error
857    * asio::error::would_block.
858    */
non_blocking() const859   bool non_blocking() const
860   {
861     return this->get_service().non_blocking(this->get_implementation());
862   }
863 
864   /// Sets the non-blocking mode of the acceptor.
865   /**
866    * @param mode If @c true, the acceptor's synchronous operations will fail
867    * with asio::error::would_block if they are unable to perform the
868    * requested operation immediately. If @c false, synchronous operations will
869    * block until complete.
870    *
871    * @throws asio::system_error Thrown on failure.
872    *
873    * @note The non-blocking mode has no effect on the behaviour of asynchronous
874    * operations. Asynchronous operations will never fail with the error
875    * asio::error::would_block.
876    */
non_blocking(bool mode)877   void non_blocking(bool mode)
878   {
879     asio::error_code ec;
880     this->get_service().non_blocking(this->get_implementation(), mode, ec);
881     asio::detail::throw_error(ec, "non_blocking");
882   }
883 
884   /// Sets the non-blocking mode of the acceptor.
885   /**
886    * @param mode If @c true, the acceptor's synchronous operations will fail
887    * with asio::error::would_block if they are unable to perform the
888    * requested operation immediately. If @c false, synchronous operations will
889    * block until complete.
890    *
891    * @param ec Set to indicate what error occurred, if any.
892    *
893    * @note The non-blocking mode has no effect on the behaviour of asynchronous
894    * operations. Asynchronous operations will never fail with the error
895    * asio::error::would_block.
896    */
non_blocking(bool mode,asio::error_code & ec)897   ASIO_SYNC_OP_VOID non_blocking(
898       bool mode, asio::error_code& ec)
899   {
900     this->get_service().non_blocking(this->get_implementation(), mode, ec);
901     ASIO_SYNC_OP_VOID_RETURN(ec);
902   }
903 
904   /// Gets the non-blocking mode of the native acceptor implementation.
905   /**
906    * This function is used to retrieve the non-blocking mode of the underlying
907    * native acceptor. This mode has no effect on the behaviour of the acceptor
908    * object's synchronous operations.
909    *
910    * @returns @c true if the underlying acceptor is in non-blocking mode and
911    * direct system calls may fail with asio::error::would_block (or the
912    * equivalent system error).
913    *
914    * @note The current non-blocking mode is cached by the acceptor object.
915    * Consequently, the return value may be incorrect if the non-blocking mode
916    * was set directly on the native acceptor.
917    */
native_non_blocking() const918   bool native_non_blocking() const
919   {
920     return this->get_service().native_non_blocking(this->get_implementation());
921   }
922 
923   /// Sets the non-blocking mode of the native acceptor implementation.
924   /**
925    * This function is used to modify the non-blocking mode of the underlying
926    * native acceptor. It has no effect on the behaviour of the acceptor object's
927    * synchronous operations.
928    *
929    * @param mode If @c true, the underlying acceptor is put into non-blocking
930    * mode and direct system calls may fail with asio::error::would_block
931    * (or the equivalent system error).
932    *
933    * @throws asio::system_error Thrown on failure. If the @c mode is
934    * @c false, but the current value of @c non_blocking() is @c true, this
935    * function fails with asio::error::invalid_argument, as the
936    * combination does not make sense.
937    */
native_non_blocking(bool mode)938   void native_non_blocking(bool mode)
939   {
940     asio::error_code ec;
941     this->get_service().native_non_blocking(
942         this->get_implementation(), mode, ec);
943     asio::detail::throw_error(ec, "native_non_blocking");
944   }
945 
946   /// Sets the non-blocking mode of the native acceptor implementation.
947   /**
948    * This function is used to modify the non-blocking mode of the underlying
949    * native acceptor. It has no effect on the behaviour of the acceptor object's
950    * synchronous operations.
951    *
952    * @param mode If @c true, the underlying acceptor is put into non-blocking
953    * mode and direct system calls may fail with asio::error::would_block
954    * (or the equivalent system error).
955    *
956    * @param ec Set to indicate what error occurred, if any. If the @c mode is
957    * @c false, but the current value of @c non_blocking() is @c true, this
958    * function fails with asio::error::invalid_argument, as the
959    * combination does not make sense.
960    */
native_non_blocking(bool mode,asio::error_code & ec)961   ASIO_SYNC_OP_VOID native_non_blocking(
962       bool mode, asio::error_code& ec)
963   {
964     this->get_service().native_non_blocking(
965         this->get_implementation(), mode, ec);
966     ASIO_SYNC_OP_VOID_RETURN(ec);
967   }
968 
969   /// Get the local endpoint of the acceptor.
970   /**
971    * This function is used to obtain the locally bound endpoint of the acceptor.
972    *
973    * @returns An object that represents the local endpoint of the acceptor.
974    *
975    * @throws asio::system_error Thrown on failure.
976    *
977    * @par Example
978    * @code
979    * asio::ip::tcp::acceptor acceptor(io_context);
980    * ...
981    * asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint();
982    * @endcode
983    */
local_endpoint() const984   endpoint_type local_endpoint() const
985   {
986     asio::error_code ec;
987     endpoint_type ep = this->get_service().local_endpoint(
988         this->get_implementation(), ec);
989     asio::detail::throw_error(ec, "local_endpoint");
990     return ep;
991   }
992 
993   /// Get the local endpoint of the acceptor.
994   /**
995    * This function is used to obtain the locally bound endpoint of the acceptor.
996    *
997    * @param ec Set to indicate what error occurred, if any.
998    *
999    * @returns An object that represents the local endpoint of the acceptor.
1000    * Returns a default-constructed endpoint object if an error occurred and the
1001    * error handler did not throw an exception.
1002    *
1003    * @par Example
1004    * @code
1005    * asio::ip::tcp::acceptor acceptor(io_context);
1006    * ...
1007    * asio::error_code ec;
1008    * asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec);
1009    * if (ec)
1010    * {
1011    *   // An error occurred.
1012    * }
1013    * @endcode
1014    */
local_endpoint(asio::error_code & ec) const1015   endpoint_type local_endpoint(asio::error_code& ec) const
1016   {
1017     return this->get_service().local_endpoint(this->get_implementation(), ec);
1018   }
1019 
1020   /// Wait for the acceptor to become ready to read, ready to write, or to have
1021   /// pending error conditions.
1022   /**
1023    * This function is used to perform a blocking wait for an acceptor to enter
1024    * a ready to read, write or error condition state.
1025    *
1026    * @param w Specifies the desired acceptor state.
1027    *
1028    * @par Example
1029    * Waiting for an acceptor to become readable.
1030    * @code
1031    * asio::ip::tcp::acceptor acceptor(io_context);
1032    * ...
1033    * acceptor.wait(asio::ip::tcp::acceptor::wait_read);
1034    * @endcode
1035    */
wait(wait_type w)1036   void wait(wait_type w)
1037   {
1038     asio::error_code ec;
1039     this->get_service().wait(this->get_implementation(), w, ec);
1040     asio::detail::throw_error(ec, "wait");
1041   }
1042 
1043   /// Wait for the acceptor to become ready to read, ready to write, or to have
1044   /// pending error conditions.
1045   /**
1046    * This function is used to perform a blocking wait for an acceptor to enter
1047    * a ready to read, write or error condition state.
1048    *
1049    * @param w Specifies the desired acceptor state.
1050    *
1051    * @param ec Set to indicate what error occurred, if any.
1052    *
1053    * @par Example
1054    * Waiting for an acceptor to become readable.
1055    * @code
1056    * asio::ip::tcp::acceptor acceptor(io_context);
1057    * ...
1058    * asio::error_code ec;
1059    * acceptor.wait(asio::ip::tcp::acceptor::wait_read, ec);
1060    * @endcode
1061    */
wait(wait_type w,asio::error_code & ec)1062   ASIO_SYNC_OP_VOID wait(wait_type w, asio::error_code& ec)
1063   {
1064     this->get_service().wait(this->get_implementation(), w, ec);
1065     ASIO_SYNC_OP_VOID_RETURN(ec);
1066   }
1067 
1068   /// Asynchronously wait for the acceptor to become ready to read, ready to
1069   /// write, or to have pending error conditions.
1070   /**
1071    * This function is used to perform an asynchronous wait for an acceptor to
1072    * enter a ready to read, write or error condition state.
1073    *
1074    * @param w Specifies the desired acceptor state.
1075    *
1076    * @param handler The handler to be called when the wait operation completes.
1077    * Copies will be made of the handler as required. The function signature of
1078    * the handler must be:
1079    * @code void handler(
1080    *   const asio::error_code& error // Result of operation
1081    * ); @endcode
1082    * Regardless of whether the asynchronous operation completes immediately or
1083    * not, the handler will not be invoked from within this function. Invocation
1084    * of the handler will be performed in a manner equivalent to using
1085    * asio::io_context::post().
1086    *
1087    * @par Example
1088    * @code
1089    * void wait_handler(const asio::error_code& error)
1090    * {
1091    *   if (!error)
1092    *   {
1093    *     // Wait succeeded.
1094    *   }
1095    * }
1096    *
1097    * ...
1098    *
1099    * asio::ip::tcp::acceptor acceptor(io_context);
1100    * ...
1101    * acceptor.async_wait(
1102    *     asio::ip::tcp::acceptor::wait_read,
1103    *     wait_handler);
1104    * @endcode
1105    */
1106   template <typename WaitHandler>
ASIO_INITFN_RESULT_TYPE(WaitHandler,void (asio::error_code))1107   ASIO_INITFN_RESULT_TYPE(WaitHandler,
1108       void (asio::error_code))
1109   async_wait(wait_type w, ASIO_MOVE_ARG(WaitHandler) handler)
1110   {
1111     // If you get an error on the following line it means that your handler does
1112     // not meet the documented type requirements for a WaitHandler.
1113     ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
1114 
1115 #if defined(ASIO_ENABLE_OLD_SERVICES)
1116     return this->get_service().async_wait(this->get_implementation(),
1117         w, ASIO_MOVE_CAST(WaitHandler)(handler));
1118 #else // defined(ASIO_ENABLE_OLD_SERVICES)
1119     async_completion<WaitHandler,
1120       void (asio::error_code)> init(handler);
1121 
1122     this->get_service().async_wait(this->get_implementation(),
1123         w, init.completion_handler);
1124 
1125     return init.result.get();
1126 #endif // defined(ASIO_ENABLE_OLD_SERVICES)
1127   }
1128 
1129 #if !defined(ASIO_NO_EXTENSIONS)
1130   /// Accept a new connection.
1131   /**
1132    * This function is used to accept a new connection from a peer into the
1133    * given socket. The function call will block until a new connection has been
1134    * accepted successfully or an error occurs.
1135    *
1136    * @param peer The socket into which the new connection will be accepted.
1137    *
1138    * @throws asio::system_error Thrown on failure.
1139    *
1140    * @par Example
1141    * @code
1142    * asio::ip::tcp::acceptor acceptor(io_context);
1143    * ...
1144    * asio::ip::tcp::socket socket(io_context);
1145    * acceptor.accept(socket);
1146    * @endcode
1147    */
1148 #if defined(ASIO_ENABLE_OLD_SERVICES)
1149   template <typename Protocol1, typename SocketService>
accept(basic_socket<Protocol1,SocketService> & peer,typename enable_if<is_convertible<Protocol,Protocol1>::value>::type * =0)1150   void accept(basic_socket<Protocol1, SocketService>& peer,
1151       typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
1152 #else // defined(ASIO_ENABLE_OLD_SERVICES)
1153   template <typename Protocol1>
1154   void accept(basic_socket<Protocol1>& peer,
1155       typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
1156 #endif // defined(ASIO_ENABLE_OLD_SERVICES)
1157   {
1158     asio::error_code ec;
1159     this->get_service().accept(this->get_implementation(),
1160         peer, static_cast<endpoint_type*>(0), ec);
1161     asio::detail::throw_error(ec, "accept");
1162   }
1163 
1164   /// Accept a new connection.
1165   /**
1166    * This function is used to accept a new connection from a peer into the
1167    * given socket. The function call will block until a new connection has been
1168    * accepted successfully or an error occurs.
1169    *
1170    * @param peer The socket into which the new connection will be accepted.
1171    *
1172    * @param ec Set to indicate what error occurred, if any.
1173    *
1174    * @par Example
1175    * @code
1176    * asio::ip::tcp::acceptor acceptor(io_context);
1177    * ...
1178    * asio::ip::tcp::socket socket(io_context);
1179    * asio::error_code ec;
1180    * acceptor.accept(socket, ec);
1181    * if (ec)
1182    * {
1183    *   // An error occurred.
1184    * }
1185    * @endcode
1186    */
1187 #if defined(ASIO_ENABLE_OLD_SERVICES)
1188   template <typename Protocol1, typename SocketService>
accept(basic_socket<Protocol1,SocketService> & peer,asio::error_code & ec,typename enable_if<is_convertible<Protocol,Protocol1>::value>::type * =0)1189   ASIO_SYNC_OP_VOID accept(
1190       basic_socket<Protocol1, SocketService>& peer,
1191       asio::error_code& ec,
1192       typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
1193 #else // defined(ASIO_ENABLE_OLD_SERVICES)
1194   template <typename Protocol1>
1195   ASIO_SYNC_OP_VOID accept(
1196       basic_socket<Protocol1>& peer, asio::error_code& ec,
1197       typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
1198 #endif // defined(ASIO_ENABLE_OLD_SERVICES)
1199   {
1200     this->get_service().accept(this->get_implementation(),
1201         peer, static_cast<endpoint_type*>(0), ec);
1202     ASIO_SYNC_OP_VOID_RETURN(ec);
1203   }
1204 
1205   /// Start an asynchronous accept.
1206   /**
1207    * This function is used to asynchronously accept a new connection into a
1208    * socket. The function call always returns immediately.
1209    *
1210    * @param peer The socket into which the new connection will be accepted.
1211    * Ownership of the peer object is retained by the caller, which must
1212    * guarantee that it is valid until the handler is called.
1213    *
1214    * @param handler The handler to be called when the accept operation
1215    * completes. Copies will be made of the handler as required. The function
1216    * signature of the handler must be:
1217    * @code void handler(
1218    *   const asio::error_code& error // Result of operation.
1219    * ); @endcode
1220    * Regardless of whether the asynchronous operation completes immediately or
1221    * not, the handler will not be invoked from within this function. Invocation
1222    * of the handler will be performed in a manner equivalent to using
1223    * asio::io_context::post().
1224    *
1225    * @par Example
1226    * @code
1227    * void accept_handler(const asio::error_code& error)
1228    * {
1229    *   if (!error)
1230    *   {
1231    *     // Accept succeeded.
1232    *   }
1233    * }
1234    *
1235    * ...
1236    *
1237    * asio::ip::tcp::acceptor acceptor(io_context);
1238    * ...
1239    * asio::ip::tcp::socket socket(io_context);
1240    * acceptor.async_accept(socket, accept_handler);
1241    * @endcode
1242    */
1243 #if defined(ASIO_ENABLE_OLD_SERVICES)
1244   template <typename Protocol1, typename SocketService, typename AcceptHandler>
ASIO_INITFN_RESULT_TYPE(AcceptHandler,void (asio::error_code))1245   ASIO_INITFN_RESULT_TYPE(AcceptHandler,
1246       void (asio::error_code))
1247   async_accept(basic_socket<Protocol1, SocketService>& peer,
1248       ASIO_MOVE_ARG(AcceptHandler) handler,
1249       typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
1250 #else // defined(ASIO_ENABLE_OLD_SERVICES)
1251   template <typename Protocol1, typename AcceptHandler>
1252   ASIO_INITFN_RESULT_TYPE(AcceptHandler,
1253       void (asio::error_code))
1254   async_accept(basic_socket<Protocol1>& peer,
1255       ASIO_MOVE_ARG(AcceptHandler) handler,
1256       typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
1257 #endif // defined(ASIO_ENABLE_OLD_SERVICES)
1258   {
1259     // If you get an error on the following line it means that your handler does
1260     // not meet the documented type requirements for a AcceptHandler.
1261     ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check;
1262 
1263 #if defined(ASIO_ENABLE_OLD_SERVICES)
1264     return this->get_service().async_accept(this->get_implementation(),
1265         peer, static_cast<endpoint_type*>(0),
1266         ASIO_MOVE_CAST(AcceptHandler)(handler));
1267 #else // defined(ASIO_ENABLE_OLD_SERVICES)
1268     async_completion<AcceptHandler,
1269       void (asio::error_code)> init(handler);
1270 
1271     this->get_service().async_accept(this->get_implementation(),
1272         peer, static_cast<endpoint_type*>(0), init.completion_handler);
1273 
1274     return init.result.get();
1275 #endif // defined(ASIO_ENABLE_OLD_SERVICES)
1276   }
1277 
1278   /// Accept a new connection and obtain the endpoint of the peer
1279   /**
1280    * This function is used to accept a new connection from a peer into the
1281    * given socket, and additionally provide the endpoint of the remote peer.
1282    * The function call will block until a new connection has been accepted
1283    * successfully or an error occurs.
1284    *
1285    * @param peer The socket into which the new connection will be accepted.
1286    *
1287    * @param peer_endpoint An endpoint object which will receive the endpoint of
1288    * the remote peer.
1289    *
1290    * @throws asio::system_error Thrown on failure.
1291    *
1292    * @par Example
1293    * @code
1294    * asio::ip::tcp::acceptor acceptor(io_context);
1295    * ...
1296    * asio::ip::tcp::socket socket(io_context);
1297    * asio::ip::tcp::endpoint endpoint;
1298    * acceptor.accept(socket, endpoint);
1299    * @endcode
1300    */
1301 #if defined(ASIO_ENABLE_OLD_SERVICES)
1302   template <typename SocketService>
accept(basic_socket<protocol_type,SocketService> & peer,endpoint_type & peer_endpoint)1303   void accept(basic_socket<protocol_type, SocketService>& peer,
1304       endpoint_type& peer_endpoint)
1305 #else // defined(ASIO_ENABLE_OLD_SERVICES)
1306   void accept(basic_socket<protocol_type>& peer, endpoint_type& peer_endpoint)
1307 #endif // defined(ASIO_ENABLE_OLD_SERVICES)
1308   {
1309     asio::error_code ec;
1310     this->get_service().accept(this->get_implementation(),
1311         peer, &peer_endpoint, ec);
1312     asio::detail::throw_error(ec, "accept");
1313   }
1314 
1315   /// Accept a new connection and obtain the endpoint of the peer
1316   /**
1317    * This function is used to accept a new connection from a peer into the
1318    * given socket, and additionally provide the endpoint of the remote peer.
1319    * The function call will block until a new connection has been accepted
1320    * successfully or an error occurs.
1321    *
1322    * @param peer The socket into which the new connection will be accepted.
1323    *
1324    * @param peer_endpoint An endpoint object which will receive the endpoint of
1325    * the remote peer.
1326    *
1327    * @param ec Set to indicate what error occurred, if any.
1328    *
1329    * @par Example
1330    * @code
1331    * asio::ip::tcp::acceptor acceptor(io_context);
1332    * ...
1333    * asio::ip::tcp::socket socket(io_context);
1334    * asio::ip::tcp::endpoint endpoint;
1335    * asio::error_code ec;
1336    * acceptor.accept(socket, endpoint, ec);
1337    * if (ec)
1338    * {
1339    *   // An error occurred.
1340    * }
1341    * @endcode
1342    */
1343 #if defined(ASIO_ENABLE_OLD_SERVICES)
1344   template <typename SocketService>
accept(basic_socket<protocol_type,SocketService> & peer,endpoint_type & peer_endpoint,asio::error_code & ec)1345   ASIO_SYNC_OP_VOID accept(
1346       basic_socket<protocol_type, SocketService>& peer,
1347       endpoint_type& peer_endpoint, asio::error_code& ec)
1348 #else // defined(ASIO_ENABLE_OLD_SERVICES)
1349   ASIO_SYNC_OP_VOID accept(basic_socket<protocol_type>& peer,
1350       endpoint_type& peer_endpoint, asio::error_code& ec)
1351 #endif // defined(ASIO_ENABLE_OLD_SERVICES)
1352   {
1353     this->get_service().accept(
1354         this->get_implementation(), peer, &peer_endpoint, ec);
1355     ASIO_SYNC_OP_VOID_RETURN(ec);
1356   }
1357 
1358   /// Start an asynchronous accept.
1359   /**
1360    * This function is used to asynchronously accept a new connection into a
1361    * socket, and additionally obtain the endpoint of the remote peer. The
1362    * function call always returns immediately.
1363    *
1364    * @param peer The socket into which the new connection will be accepted.
1365    * Ownership of the peer object is retained by the caller, which must
1366    * guarantee that it is valid until the handler is called.
1367    *
1368    * @param peer_endpoint An endpoint object into which the endpoint of the
1369    * remote peer will be written. Ownership of the peer_endpoint object is
1370    * retained by the caller, which must guarantee that it is valid until the
1371    * handler is called.
1372    *
1373    * @param handler The handler to be called when the accept operation
1374    * completes. Copies will be made of the handler as required. The function
1375    * signature of the handler must be:
1376    * @code void handler(
1377    *   const asio::error_code& error // Result of operation.
1378    * ); @endcode
1379    * Regardless of whether the asynchronous operation completes immediately or
1380    * not, the handler will not be invoked from within this function. Invocation
1381    * of the handler will be performed in a manner equivalent to using
1382    * asio::io_context::post().
1383    */
1384 #if defined(ASIO_ENABLE_OLD_SERVICES)
1385   template <typename SocketService, typename AcceptHandler>
ASIO_INITFN_RESULT_TYPE(AcceptHandler,void (asio::error_code))1386   ASIO_INITFN_RESULT_TYPE(AcceptHandler,
1387       void (asio::error_code))
1388   async_accept(basic_socket<protocol_type, SocketService>& peer,
1389       endpoint_type& peer_endpoint, ASIO_MOVE_ARG(AcceptHandler) handler)
1390 #else // defined(ASIO_ENABLE_OLD_SERVICES)
1391   template <typename AcceptHandler>
1392   ASIO_INITFN_RESULT_TYPE(AcceptHandler,
1393       void (asio::error_code))
1394   async_accept(basic_socket<protocol_type>& peer,
1395       endpoint_type& peer_endpoint, ASIO_MOVE_ARG(AcceptHandler) handler)
1396 #endif // defined(ASIO_ENABLE_OLD_SERVICES)
1397   {
1398     // If you get an error on the following line it means that your handler does
1399     // not meet the documented type requirements for a AcceptHandler.
1400     ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check;
1401 
1402 #if defined(ASIO_ENABLE_OLD_SERVICES)
1403     return this->get_service().async_accept(this->get_implementation(), peer,
1404         &peer_endpoint, ASIO_MOVE_CAST(AcceptHandler)(handler));
1405 #else // defined(ASIO_ENABLE_OLD_SERVICES)
1406     async_completion<AcceptHandler,
1407       void (asio::error_code)> init(handler);
1408 
1409     this->get_service().async_accept(this->get_implementation(),
1410         peer, &peer_endpoint, init.completion_handler);
1411 
1412     return init.result.get();
1413 #endif // defined(ASIO_ENABLE_OLD_SERVICES)
1414   }
1415 #endif // !defined(ASIO_NO_EXTENSIONS)
1416 
1417 #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
1418   /// Accept a new connection.
1419   /**
1420    * This function is used to accept a new connection from a peer. The function
1421    * call will block until a new connection has been accepted successfully or
1422    * an error occurs.
1423    *
1424    * This overload requires that the Protocol template parameter satisfy the
1425    * AcceptableProtocol type requirements.
1426    *
1427    * @returns A socket object representing the newly accepted connection.
1428    *
1429    * @throws asio::system_error Thrown on failure.
1430    *
1431    * @par Example
1432    * @code
1433    * asio::ip::tcp::acceptor acceptor(io_context);
1434    * ...
1435    * asio::ip::tcp::socket socket(acceptor.accept());
1436    * @endcode
1437    */
accept()1438   typename Protocol::socket accept()
1439   {
1440     asio::error_code ec;
1441     typename Protocol::socket peer(
1442         this->get_service().accept(
1443           this->get_implementation(), 0, 0, ec));
1444     asio::detail::throw_error(ec, "accept");
1445     return peer;
1446   }
1447 
1448   /// Accept a new connection.
1449   /**
1450    * This function is used to accept a new connection from a peer. The function
1451    * call will block until a new connection has been accepted successfully or
1452    * an error occurs.
1453    *
1454    * This overload requires that the Protocol template parameter satisfy the
1455    * AcceptableProtocol type requirements.
1456    *
1457    * @param ec Set to indicate what error occurred, if any.
1458    *
1459    * @returns On success, a socket object representing the newly accepted
1460    * connection. On error, a socket object where is_open() is false.
1461    *
1462    * @par Example
1463    * @code
1464    * asio::ip::tcp::acceptor acceptor(io_context);
1465    * ...
1466    * asio::ip::tcp::socket socket(acceptor.accept(ec));
1467    * if (ec)
1468    * {
1469    *   // An error occurred.
1470    * }
1471    * @endcode
1472    */
accept(asio::error_code & ec)1473   typename Protocol::socket accept(asio::error_code& ec)
1474   {
1475     return this->get_service().accept(this->get_implementation(), 0, 0, ec);
1476   }
1477 
1478   /// Start an asynchronous accept.
1479   /**
1480    * This function is used to asynchronously accept a new connection. The
1481    * function call always returns immediately.
1482    *
1483    * This overload requires that the Protocol template parameter satisfy the
1484    * AcceptableProtocol type requirements.
1485    *
1486    * @param handler The handler to be called when the accept operation
1487    * completes. Copies will be made of the handler as required. The function
1488    * signature of the handler must be:
1489    * @code void handler(
1490    *   const asio::error_code& error, // Result of operation.
1491    *   typename Protocol::socket peer // On success, the newly accepted socket.
1492    * ); @endcode
1493    * Regardless of whether the asynchronous operation completes immediately or
1494    * not, the handler will not be invoked from within this function. Invocation
1495    * of the handler will be performed in a manner equivalent to using
1496    * asio::io_context::post().
1497    *
1498    * @par Example
1499    * @code
1500    * void accept_handler(const asio::error_code& error,
1501    *     asio::ip::tcp::socket peer)
1502    * {
1503    *   if (!error)
1504    *   {
1505    *     // Accept succeeded.
1506    *   }
1507    * }
1508    *
1509    * ...
1510    *
1511    * asio::ip::tcp::acceptor acceptor(io_context);
1512    * ...
1513    * acceptor.async_accept(accept_handler);
1514    * @endcode
1515    */
1516   template <typename MoveAcceptHandler>
ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,void (asio::error_code,typename Protocol::socket))1517   ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,
1518       void (asio::error_code, typename Protocol::socket))
1519   async_accept(ASIO_MOVE_ARG(MoveAcceptHandler) handler)
1520   {
1521     // If you get an error on the following line it means that your handler does
1522     // not meet the documented type requirements for a MoveAcceptHandler.
1523     ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler,
1524         handler, typename Protocol::socket) type_check;
1525 
1526 #if defined(ASIO_ENABLE_OLD_SERVICES)
1527     return this->get_service().async_accept(
1528         this->get_implementation(), static_cast<asio::io_context*>(0),
1529         static_cast<endpoint_type*>(0),
1530         ASIO_MOVE_CAST(MoveAcceptHandler)(handler));
1531 #else // defined(ASIO_ENABLE_OLD_SERVICES)
1532     async_completion<MoveAcceptHandler,
1533       void (asio::error_code,
1534         typename Protocol::socket)> init(handler);
1535 
1536     this->get_service().async_accept(
1537         this->get_implementation(), static_cast<asio::io_context*>(0),
1538         static_cast<endpoint_type*>(0), init.completion_handler);
1539 
1540     return init.result.get();
1541 #endif // defined(ASIO_ENABLE_OLD_SERVICES)
1542   }
1543 
1544   /// Accept a new connection.
1545   /**
1546    * This function is used to accept a new connection from a peer. The function
1547    * call will block until a new connection has been accepted successfully or
1548    * an error occurs.
1549    *
1550    * This overload requires that the Protocol template parameter satisfy the
1551    * AcceptableProtocol type requirements.
1552    *
1553    * @param io_context The io_context object to be used for the newly accepted
1554    * socket.
1555    *
1556    * @returns A socket object representing the newly accepted connection.
1557    *
1558    * @throws asio::system_error Thrown on failure.
1559    *
1560    * @par Example
1561    * @code
1562    * asio::ip::tcp::acceptor acceptor(io_context);
1563    * ...
1564    * asio::ip::tcp::socket socket(acceptor.accept());
1565    * @endcode
1566    */
accept(asio::io_context & io_context)1567   typename Protocol::socket accept(asio::io_context& io_context)
1568   {
1569     asio::error_code ec;
1570     typename Protocol::socket peer(
1571         this->get_service().accept(this->get_implementation(),
1572           &io_context, static_cast<endpoint_type*>(0), ec));
1573     asio::detail::throw_error(ec, "accept");
1574     return peer;
1575   }
1576 
1577   /// Accept a new connection.
1578   /**
1579    * This function is used to accept a new connection from a peer. The function
1580    * call will block until a new connection has been accepted successfully or
1581    * an error occurs.
1582    *
1583    * This overload requires that the Protocol template parameter satisfy the
1584    * AcceptableProtocol type requirements.
1585    *
1586    * @param io_context The io_context object to be used for the newly accepted
1587    * socket.
1588    *
1589    * @param ec Set to indicate what error occurred, if any.
1590    *
1591    * @returns On success, a socket object representing the newly accepted
1592    * connection. On error, a socket object where is_open() is false.
1593    *
1594    * @par Example
1595    * @code
1596    * asio::ip::tcp::acceptor acceptor(io_context);
1597    * ...
1598    * asio::ip::tcp::socket socket(acceptor.accept(io_context2, ec));
1599    * if (ec)
1600    * {
1601    *   // An error occurred.
1602    * }
1603    * @endcode
1604    */
accept(asio::io_context & io_context,asio::error_code & ec)1605   typename Protocol::socket accept(
1606       asio::io_context& io_context, asio::error_code& ec)
1607   {
1608     return this->get_service().accept(this->get_implementation(),
1609         &io_context, static_cast<endpoint_type*>(0), ec);
1610   }
1611 
1612   /// Start an asynchronous accept.
1613   /**
1614    * This function is used to asynchronously accept a new connection. The
1615    * function call always returns immediately.
1616    *
1617    * This overload requires that the Protocol template parameter satisfy the
1618    * AcceptableProtocol type requirements.
1619    *
1620    * @param io_context The io_context object to be used for the newly accepted
1621    * socket.
1622    *
1623    * @param handler The handler to be called when the accept operation
1624    * completes. Copies will be made of the handler as required. The function
1625    * signature of the handler must be:
1626    * @code void handler(
1627    *   const asio::error_code& error, // Result of operation.
1628    *   typename Protocol::socket peer // On success, the newly accepted socket.
1629    * ); @endcode
1630    * Regardless of whether the asynchronous operation completes immediately or
1631    * not, the handler will not be invoked from within this function. Invocation
1632    * of the handler will be performed in a manner equivalent to using
1633    * asio::io_context::post().
1634    *
1635    * @par Example
1636    * @code
1637    * void accept_handler(const asio::error_code& error,
1638    *     asio::ip::tcp::socket peer)
1639    * {
1640    *   if (!error)
1641    *   {
1642    *     // Accept succeeded.
1643    *   }
1644    * }
1645    *
1646    * ...
1647    *
1648    * asio::ip::tcp::acceptor acceptor(io_context);
1649    * ...
1650    * acceptor.async_accept(io_context2, accept_handler);
1651    * @endcode
1652    */
1653   template <typename MoveAcceptHandler>
ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,void (asio::error_code,typename Protocol::socket))1654   ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,
1655       void (asio::error_code, typename Protocol::socket))
1656   async_accept(asio::io_context& io_context,
1657       ASIO_MOVE_ARG(MoveAcceptHandler) handler)
1658   {
1659     // If you get an error on the following line it means that your handler does
1660     // not meet the documented type requirements for a MoveAcceptHandler.
1661     ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler,
1662         handler, typename Protocol::socket) type_check;
1663 
1664 #if defined(ASIO_ENABLE_OLD_SERVICES)
1665     return this->get_service().async_accept(this->get_implementation(),
1666         &io_context, static_cast<endpoint_type*>(0),
1667         ASIO_MOVE_CAST(MoveAcceptHandler)(handler));
1668 #else // defined(ASIO_ENABLE_OLD_SERVICES)
1669     async_completion<MoveAcceptHandler,
1670       void (asio::error_code,
1671         typename Protocol::socket)> init(handler);
1672 
1673     this->get_service().async_accept(this->get_implementation(),
1674         &io_context, static_cast<endpoint_type*>(0), init.completion_handler);
1675 
1676     return init.result.get();
1677 #endif // defined(ASIO_ENABLE_OLD_SERVICES)
1678   }
1679 
1680   /// Accept a new connection.
1681   /**
1682    * This function is used to accept a new connection from a peer. The function
1683    * call will block until a new connection has been accepted successfully or
1684    * an error occurs.
1685    *
1686    * This overload requires that the Protocol template parameter satisfy the
1687    * AcceptableProtocol type requirements.
1688    *
1689    * @param peer_endpoint An endpoint object into which the endpoint of the
1690    * remote peer will be written.
1691    *
1692    * @returns A socket object representing the newly accepted connection.
1693    *
1694    * @throws asio::system_error Thrown on failure.
1695    *
1696    * @par Example
1697    * @code
1698    * asio::ip::tcp::acceptor acceptor(io_context);
1699    * ...
1700    * asio::ip::tcp::endpoint endpoint;
1701    * asio::ip::tcp::socket socket(acceptor.accept(endpoint));
1702    * @endcode
1703    */
accept(endpoint_type & peer_endpoint)1704   typename Protocol::socket accept(endpoint_type& peer_endpoint)
1705   {
1706     asio::error_code ec;
1707     typename Protocol::socket peer(
1708         this->get_service().accept(this->get_implementation(),
1709           static_cast<asio::io_context*>(0), &peer_endpoint, ec));
1710     asio::detail::throw_error(ec, "accept");
1711     return peer;
1712   }
1713 
1714   /// Accept a new connection.
1715   /**
1716    * This function is used to accept a new connection from a peer. The function
1717    * call will block until a new connection has been accepted successfully or
1718    * an error occurs.
1719    *
1720    * This overload requires that the Protocol template parameter satisfy the
1721    * AcceptableProtocol type requirements.
1722    *
1723    * @param peer_endpoint An endpoint object into which the endpoint of the
1724    * remote peer will be written.
1725    *
1726    * @param ec Set to indicate what error occurred, if any.
1727    *
1728    * @returns On success, a socket object representing the newly accepted
1729    * connection. On error, a socket object where is_open() is false.
1730    *
1731    * @par Example
1732    * @code
1733    * asio::ip::tcp::acceptor acceptor(io_context);
1734    * ...
1735    * asio::ip::tcp::endpoint endpoint;
1736    * asio::ip::tcp::socket socket(acceptor.accept(endpoint, ec));
1737    * if (ec)
1738    * {
1739    *   // An error occurred.
1740    * }
1741    * @endcode
1742    */
accept(endpoint_type & peer_endpoint,asio::error_code & ec)1743   typename Protocol::socket accept(
1744       endpoint_type& peer_endpoint, asio::error_code& ec)
1745   {
1746     return this->get_service().accept(this->get_implementation(),
1747         static_cast<asio::io_context*>(0), &peer_endpoint, ec);
1748   }
1749 
1750   /// Start an asynchronous accept.
1751   /**
1752    * This function is used to asynchronously accept a new connection. The
1753    * function call always returns immediately.
1754    *
1755    * This overload requires that the Protocol template parameter satisfy the
1756    * AcceptableProtocol type requirements.
1757    *
1758    * @param peer_endpoint An endpoint object into which the endpoint of the
1759    * remote peer will be written. Ownership of the peer_endpoint object is
1760    * retained by the caller, which must guarantee that it is valid until the
1761    * handler is called.
1762    *
1763    * @param handler The handler to be called when the accept operation
1764    * completes. Copies will be made of the handler as required. The function
1765    * signature of the handler must be:
1766    * @code void handler(
1767    *   const asio::error_code& error, // Result of operation.
1768    *   typename Protocol::socket peer // On success, the newly accepted socket.
1769    * ); @endcode
1770    * Regardless of whether the asynchronous operation completes immediately or
1771    * not, the handler will not be invoked from within this function. Invocation
1772    * of the handler will be performed in a manner equivalent to using
1773    * asio::io_context::post().
1774    *
1775    * @par Example
1776    * @code
1777    * void accept_handler(const asio::error_code& error,
1778    *     asio::ip::tcp::socket peer)
1779    * {
1780    *   if (!error)
1781    *   {
1782    *     // Accept succeeded.
1783    *   }
1784    * }
1785    *
1786    * ...
1787    *
1788    * asio::ip::tcp::acceptor acceptor(io_context);
1789    * ...
1790    * asio::ip::tcp::endpoint endpoint;
1791    * acceptor.async_accept(endpoint, accept_handler);
1792    * @endcode
1793    */
1794   template <typename MoveAcceptHandler>
ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,void (asio::error_code,typename Protocol::socket))1795   ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,
1796       void (asio::error_code, typename Protocol::socket))
1797   async_accept(endpoint_type& peer_endpoint,
1798       ASIO_MOVE_ARG(MoveAcceptHandler) handler)
1799   {
1800     // If you get an error on the following line it means that your handler does
1801     // not meet the documented type requirements for a MoveAcceptHandler.
1802     ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler,
1803         handler, typename Protocol::socket) type_check;
1804 
1805 #if defined(ASIO_ENABLE_OLD_SERVICES)
1806     return this->get_service().async_accept(this->get_implementation(),
1807         static_cast<asio::io_context*>(0), &peer_endpoint,
1808         ASIO_MOVE_CAST(MoveAcceptHandler)(handler));
1809 #else // defined(ASIO_ENABLE_OLD_SERVICES)
1810     async_completion<MoveAcceptHandler,
1811       void (asio::error_code,
1812         typename Protocol::socket)> init(handler);
1813 
1814     this->get_service().async_accept(this->get_implementation(),
1815         static_cast<asio::io_context*>(0), &peer_endpoint,
1816         init.completion_handler);
1817 
1818     return init.result.get();
1819 #endif // defined(ASIO_ENABLE_OLD_SERVICES)
1820   }
1821 
1822   /// Accept a new connection.
1823   /**
1824    * This function is used to accept a new connection from a peer. The function
1825    * call will block until a new connection has been accepted successfully or
1826    * an error occurs.
1827    *
1828    * This overload requires that the Protocol template parameter satisfy the
1829    * AcceptableProtocol type requirements.
1830    *
1831    * @param io_context The io_context object to be used for the newly accepted
1832    * socket.
1833    *
1834    * @param peer_endpoint An endpoint object into which the endpoint of the
1835    * remote peer will be written.
1836    *
1837    * @returns A socket object representing the newly accepted connection.
1838    *
1839    * @throws asio::system_error Thrown on failure.
1840    *
1841    * @par Example
1842    * @code
1843    * asio::ip::tcp::acceptor acceptor(io_context);
1844    * ...
1845    * asio::ip::tcp::endpoint endpoint;
1846    * asio::ip::tcp::socket socket(
1847    *     acceptor.accept(io_context2, endpoint));
1848    * @endcode
1849    */
accept(asio::io_context & io_context,endpoint_type & peer_endpoint)1850   typename Protocol::socket accept(
1851       asio::io_context& io_context, endpoint_type& peer_endpoint)
1852   {
1853     asio::error_code ec;
1854     typename Protocol::socket peer(
1855         this->get_service().accept(this->get_implementation(),
1856           &io_context, &peer_endpoint, ec));
1857     asio::detail::throw_error(ec, "accept");
1858     return peer;
1859   }
1860 
1861   /// Accept a new connection.
1862   /**
1863    * This function is used to accept a new connection from a peer. The function
1864    * call will block until a new connection has been accepted successfully or
1865    * an error occurs.
1866    *
1867    * This overload requires that the Protocol template parameter satisfy the
1868    * AcceptableProtocol type requirements.
1869    *
1870    * @param io_context The io_context object to be used for the newly accepted
1871    * socket.
1872    *
1873    * @param peer_endpoint An endpoint object into which the endpoint of the
1874    * remote peer will be written.
1875    *
1876    * @param ec Set to indicate what error occurred, if any.
1877    *
1878    * @returns On success, a socket object representing the newly accepted
1879    * connection. On error, a socket object where is_open() is false.
1880    *
1881    * @par Example
1882    * @code
1883    * asio::ip::tcp::acceptor acceptor(io_context);
1884    * ...
1885    * asio::ip::tcp::endpoint endpoint;
1886    * asio::ip::tcp::socket socket(
1887    *     acceptor.accept(io_context2, endpoint, ec));
1888    * if (ec)
1889    * {
1890    *   // An error occurred.
1891    * }
1892    * @endcode
1893    */
accept(asio::io_context & io_context,endpoint_type & peer_endpoint,asio::error_code & ec)1894   typename Protocol::socket accept(asio::io_context& io_context,
1895       endpoint_type& peer_endpoint, asio::error_code& ec)
1896   {
1897     return this->get_service().accept(this->get_implementation(),
1898         &io_context, &peer_endpoint, ec);
1899   }
1900 
1901   /// Start an asynchronous accept.
1902   /**
1903    * This function is used to asynchronously accept a new connection. The
1904    * function call always returns immediately.
1905    *
1906    * This overload requires that the Protocol template parameter satisfy the
1907    * AcceptableProtocol type requirements.
1908    *
1909    * @param io_context The io_context object to be used for the newly accepted
1910    * socket.
1911    *
1912    * @param peer_endpoint An endpoint object into which the endpoint of the
1913    * remote peer will be written. Ownership of the peer_endpoint object is
1914    * retained by the caller, which must guarantee that it is valid until the
1915    * handler is called.
1916    *
1917    * @param handler The handler to be called when the accept operation
1918    * completes. Copies will be made of the handler as required. The function
1919    * signature of the handler must be:
1920    * @code void handler(
1921    *   const asio::error_code& error, // Result of operation.
1922    *   typename Protocol::socket peer // On success, the newly accepted socket.
1923    * ); @endcode
1924    * Regardless of whether the asynchronous operation completes immediately or
1925    * not, the handler will not be invoked from within this function. Invocation
1926    * of the handler will be performed in a manner equivalent to using
1927    * asio::io_context::post().
1928    *
1929    * @par Example
1930    * @code
1931    * void accept_handler(const asio::error_code& error,
1932    *     asio::ip::tcp::socket peer)
1933    * {
1934    *   if (!error)
1935    *   {
1936    *     // Accept succeeded.
1937    *   }
1938    * }
1939    *
1940    * ...
1941    *
1942    * asio::ip::tcp::acceptor acceptor(io_context);
1943    * ...
1944    * asio::ip::tcp::endpoint endpoint;
1945    * acceptor.async_accept(io_context2, endpoint, accept_handler);
1946    * @endcode
1947    */
1948   template <typename MoveAcceptHandler>
ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,void (asio::error_code,typename Protocol::socket))1949   ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,
1950       void (asio::error_code, typename Protocol::socket))
1951   async_accept(asio::io_context& io_context,
1952       endpoint_type& peer_endpoint,
1953       ASIO_MOVE_ARG(MoveAcceptHandler) handler)
1954   {
1955     // If you get an error on the following line it means that your handler does
1956     // not meet the documented type requirements for a MoveAcceptHandler.
1957     ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler,
1958         handler, typename Protocol::socket) type_check;
1959 
1960 #if defined(ASIO_ENABLE_OLD_SERVICES)
1961     return this->get_service().async_accept(
1962         this->get_implementation(), &io_context, &peer_endpoint,
1963         ASIO_MOVE_CAST(MoveAcceptHandler)(handler));
1964 #else // defined(ASIO_ENABLE_OLD_SERVICES)
1965     async_completion<MoveAcceptHandler,
1966       void (asio::error_code,
1967         typename Protocol::socket)> init(handler);
1968 
1969     this->get_service().async_accept(this->get_implementation(),
1970         &io_context, &peer_endpoint, init.completion_handler);
1971 
1972     return init.result.get();
1973 #endif // defined(ASIO_ENABLE_OLD_SERVICES)
1974   }
1975 #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
1976 };
1977 
1978 } // namespace asio
1979 
1980 #include "asio/detail/pop_options.hpp"
1981 
1982 #if !defined(ASIO_ENABLE_OLD_SERVICES)
1983 # undef ASIO_SVC_T
1984 #endif // !defined(ASIO_ENABLE_OLD_SERVICES)
1985 
1986 #endif // ASIO_BASIC_SOCKET_ACCEPTOR_HPP
1987