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