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