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