Clementine
basic_socket_acceptor.hpp
1 //
2 // basic_socket_acceptor.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 //
10 
11 #ifndef ASIO_BASIC_SOCKET_ACCEPTOR_HPP
12 #define ASIO_BASIC_SOCKET_ACCEPTOR_HPP
13 
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17 
18 #include "asio/detail/config.hpp"
19 #include "asio/any_io_executor.hpp"
20 #include "asio/basic_socket.hpp"
21 #include "asio/detail/handler_type_requirements.hpp"
22 #include "asio/detail/io_object_impl.hpp"
23 #include "asio/detail/non_const_lvalue.hpp"
24 #include "asio/detail/throw_error.hpp"
25 #include "asio/detail/type_traits.hpp"
26 #include "asio/error.hpp"
27 #include "asio/execution_context.hpp"
28 #include "asio/socket_base.hpp"
29 
30 #if defined(ASIO_WINDOWS_RUNTIME)
31 # include "asio/detail/null_socket_service.hpp"
32 #elif defined(ASIO_HAS_IOCP)
33 # include "asio/detail/win_iocp_socket_service.hpp"
34 #else
35 # include "asio/detail/reactive_socket_service.hpp"
36 #endif
37 
38 #if defined(ASIO_HAS_MOVE)
39 # include <utility>
40 #endif // defined(ASIO_HAS_MOVE)
41 
42 #include "asio/detail/push_options.hpp"
43 
44 namespace asio {
45 
46 #if !defined(ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL)
47 #define ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL
48 
49 // Forward declaration with defaulted arguments.
50 template <typename Protocol, typename Executor = any_io_executor>
52 
53 #endif // !defined(ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL)
54 
56 
75 template <typename Protocol, typename Executor>
77  : public socket_base
78 {
79 public:
81  typedef Executor executor_type;
82 
84  template <typename Executor1>
86  {
89  };
90 
92 #if defined(GENERATING_DOCUMENTATION)
93  typedef implementation_defined native_handle_type;
94 #elif defined(ASIO_WINDOWS_RUNTIME)
95  typedef typename detail::null_socket_service<
97 #elif defined(ASIO_HAS_IOCP)
98  typedef typename detail::win_iocp_socket_service<
100 #else
101  typedef typename detail::reactive_socket_service<
103 #endif
104 
106  typedef Protocol protocol_type;
107 
109  typedef typename Protocol::endpoint endpoint_type;
110 
112 
121  explicit basic_socket_acceptor(const executor_type& ex)
122  : impl_(ex)
123  {
124  }
125 
127 
136  template <typename ExecutionContext>
137  explicit basic_socket_acceptor(ExecutionContext& context,
138  typename enable_if<
139  is_convertible<ExecutionContext&, execution_context&>::value
140  >::type* = 0)
141  : impl_(context)
142  {
143  }
144 
146 
157  basic_socket_acceptor(const executor_type& ex, const protocol_type& protocol)
158  : impl_(ex)
159  {
160  asio::error_code ec;
161  impl_.get_service().open(impl_.get_implementation(), protocol, ec);
162  asio::detail::throw_error(ec, "open");
163  }
164 
166 
177  template <typename ExecutionContext>
178  basic_socket_acceptor(ExecutionContext& context,
179  const protocol_type& protocol,
180  typename enable_if<
181  is_convertible<ExecutionContext&, execution_context&>::value
182  >::type* = 0)
183  : impl_(context)
184  {
185  asio::error_code ec;
186  impl_.get_service().open(impl_.get_implementation(), protocol, ec);
187  asio::detail::throw_error(ec, "open");
188  }
189 
191 
217  basic_socket_acceptor(const executor_type& ex,
218  const endpoint_type& endpoint, bool reuse_addr = true)
219  : impl_(ex)
220  {
221  asio::error_code ec;
222  const protocol_type protocol = endpoint.protocol();
223  impl_.get_service().open(impl_.get_implementation(), protocol, ec);
224  asio::detail::throw_error(ec, "open");
225  if (reuse_addr)
226  {
227  impl_.get_service().set_option(impl_.get_implementation(),
228  socket_base::reuse_address(true), ec);
229  asio::detail::throw_error(ec, "set_option");
230  }
231  impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
232  asio::detail::throw_error(ec, "bind");
233  impl_.get_service().listen(impl_.get_implementation(),
234  socket_base::max_listen_connections, ec);
235  asio::detail::throw_error(ec, "listen");
236  }
237 
239 
265  template <typename ExecutionContext>
266  basic_socket_acceptor(ExecutionContext& context,
267  const endpoint_type& endpoint, bool reuse_addr = true,
268  typename enable_if<
269  is_convertible<ExecutionContext&, execution_context&>::value
270  >::type* = 0)
271  : impl_(context)
272  {
273  asio::error_code ec;
274  const protocol_type protocol = endpoint.protocol();
275  impl_.get_service().open(impl_.get_implementation(), protocol, ec);
276  asio::detail::throw_error(ec, "open");
277  if (reuse_addr)
278  {
279  impl_.get_service().set_option(impl_.get_implementation(),
280  socket_base::reuse_address(true), ec);
281  asio::detail::throw_error(ec, "set_option");
282  }
283  impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
284  asio::detail::throw_error(ec, "bind");
285  impl_.get_service().listen(impl_.get_implementation(),
286  socket_base::max_listen_connections, ec);
287  asio::detail::throw_error(ec, "listen");
288  }
289 
291 
305  basic_socket_acceptor(const executor_type& ex,
306  const protocol_type& protocol, const native_handle_type& native_acceptor)
307  : impl_(ex)
308  {
309  asio::error_code ec;
310  impl_.get_service().assign(impl_.get_implementation(),
311  protocol, native_acceptor, ec);
312  asio::detail::throw_error(ec, "assign");
313  }
314 
316 
330  template <typename ExecutionContext>
331  basic_socket_acceptor(ExecutionContext& context,
332  const protocol_type& protocol, const native_handle_type& native_acceptor,
333  typename enable_if<
334  is_convertible<ExecutionContext&, execution_context&>::value
335  >::type* = 0)
336  : impl_(context)
337  {
338  asio::error_code ec;
339  impl_.get_service().assign(impl_.get_implementation(),
340  protocol, native_acceptor, ec);
341  asio::detail::throw_error(ec, "assign");
342  }
343 
344 #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
345 
357  : impl_(std::move(other.impl_))
358  {
359  }
360 
362 
373  {
374  impl_ = std::move(other.impl_);
375  return *this;
376  }
377 
378  // All socket acceptors have access to each other's implementations.
379  template <typename Protocol1, typename Executor1>
380  friend class basic_socket_acceptor;
381 
384 
394  template <typename Protocol1, typename Executor1>
396  typename enable_if<
397  is_convertible<Protocol1, Protocol>::value
398  && is_convertible<Executor1, Executor>::value
399  >::type* = 0)
400  : impl_(std::move(other.impl_))
401  {
402  }
403 
406 
416  template <typename Protocol1, typename Executor1>
417  typename enable_if<
418  is_convertible<Protocol1, Protocol>::value
419  && is_convertible<Executor1, Executor>::value,
422  {
423  basic_socket_acceptor tmp(std::move(other));
424  impl_ = std::move(tmp.impl_);
425  return *this;
426  }
427 #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
428 
430 
436  {
437  }
438 
440  executor_type get_executor() ASIO_NOEXCEPT
441  {
442  return impl_.get_executor();
443  }
444 
446 
460  void open(const protocol_type& protocol = protocol_type())
461  {
462  asio::error_code ec;
463  impl_.get_service().open(impl_.get_implementation(), protocol, ec);
464  asio::detail::throw_error(ec, "open");
465  }
466 
468 
487  ASIO_SYNC_OP_VOID open(const protocol_type& protocol,
488  asio::error_code& ec)
489  {
490  impl_.get_service().open(impl_.get_implementation(), protocol, ec);
491  ASIO_SYNC_OP_VOID_RETURN(ec);
492  }
493 
495  /*
496  * This function opens the acceptor to hold an existing native acceptor.
497  *
498  * @param protocol An object specifying which protocol is to be used.
499  *
500  * @param native_acceptor A native acceptor.
501  *
502  * @throws asio::system_error Thrown on failure.
503  */
504  void assign(const protocol_type& protocol,
505  const native_handle_type& native_acceptor)
506  {
507  asio::error_code ec;
508  impl_.get_service().assign(impl_.get_implementation(),
509  protocol, native_acceptor, ec);
510  asio::detail::throw_error(ec, "assign");
511  }
512 
514  /*
515  * This function opens the acceptor to hold an existing native acceptor.
516  *
517  * @param protocol An object specifying which protocol is to be used.
518  *
519  * @param native_acceptor A native acceptor.
520  *
521  * @param ec Set to indicate what error occurred, if any.
522  */
523  ASIO_SYNC_OP_VOID assign(const protocol_type& protocol,
524  const native_handle_type& native_acceptor, asio::error_code& ec)
525  {
526  impl_.get_service().assign(impl_.get_implementation(),
527  protocol, native_acceptor, ec);
528  ASIO_SYNC_OP_VOID_RETURN(ec);
529  }
530 
532  bool is_open() const
533  {
534  return impl_.get_service().is_open(impl_.get_implementation());
535  }
536 
538 
555  void bind(const endpoint_type& endpoint)
556  {
557  asio::error_code ec;
558  impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
559  asio::detail::throw_error(ec, "bind");
560  }
561 
563 
585  ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint,
586  asio::error_code& ec)
587  {
588  impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
589  ASIO_SYNC_OP_VOID_RETURN(ec);
590  }
591 
594 
602  void listen(int backlog = socket_base::max_listen_connections)
603  {
604  asio::error_code ec;
605  impl_.get_service().listen(impl_.get_implementation(), backlog, ec);
606  asio::detail::throw_error(ec, "listen");
607  }
608 
611 
631  ASIO_SYNC_OP_VOID listen(int backlog, asio::error_code& ec)
632  {
633  impl_.get_service().listen(impl_.get_implementation(), backlog, ec);
634  ASIO_SYNC_OP_VOID_RETURN(ec);
635  }
636 
638 
647  void close()
648  {
649  asio::error_code ec;
650  impl_.get_service().close(impl_.get_implementation(), ec);
651  asio::detail::throw_error(ec, "close");
652  }
653 
655 
676  ASIO_SYNC_OP_VOID close(asio::error_code& ec)
677  {
678  impl_.get_service().close(impl_.get_implementation(), ec);
679  ASIO_SYNC_OP_VOID_RETURN(ec);
680  }
681 
683 
695 #if defined(ASIO_MSVC) && (ASIO_MSVC >= 1400) \
696  && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
697  __declspec(deprecated("This function always fails with "
698  "operation_not_supported when used on Windows versions "
699  "prior to Windows 8.1."))
700 #endif
701  native_handle_type release()
702  {
703  asio::error_code ec;
704  native_handle_type s = impl_.get_service().release(
705  impl_.get_implementation(), ec);
706  asio::detail::throw_error(ec, "release");
707  return s;
708  }
709 
711 
723 #if defined(ASIO_MSVC) && (ASIO_MSVC >= 1400) \
724  && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
725  __declspec(deprecated("This function always fails with "
726  "operation_not_supported when used on Windows versions "
727  "prior to Windows 8.1."))
728 #endif
729  native_handle_type release(asio::error_code& ec)
730  {
731  return impl_.get_service().release(impl_.get_implementation(), ec);
732  }
733 
735 
740  native_handle_type native_handle()
741  {
742  return impl_.get_service().native_handle(impl_.get_implementation());
743  }
744 
746 
753  void cancel()
754  {
755  asio::error_code ec;
756  impl_.get_service().cancel(impl_.get_implementation(), ec);
757  asio::detail::throw_error(ec, "cancel");
758  }
759 
761 
768  ASIO_SYNC_OP_VOID cancel(asio::error_code& ec)
769  {
770  impl_.get_service().cancel(impl_.get_implementation(), ec);
771  ASIO_SYNC_OP_VOID_RETURN(ec);
772  }
773 
775 
795  template <typename SettableSocketOption>
796  void set_option(const SettableSocketOption& option)
797  {
798  asio::error_code ec;
799  impl_.get_service().set_option(impl_.get_implementation(), option, ec);
800  asio::detail::throw_error(ec, "set_option");
801  }
802 
804 
829  template <typename SettableSocketOption>
830  ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option,
831  asio::error_code& ec)
832  {
833  impl_.get_service().set_option(impl_.get_implementation(), option, ec);
834  ASIO_SYNC_OP_VOID_RETURN(ec);
835  }
836 
838 
859  template <typename GettableSocketOption>
860  void get_option(GettableSocketOption& option) const
861  {
862  asio::error_code ec;
863  impl_.get_service().get_option(impl_.get_implementation(), option, ec);
864  asio::detail::throw_error(ec, "get_option");
865  }
866 
868 
894  template <typename GettableSocketOption>
895  ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option,
896  asio::error_code& ec) const
897  {
898  impl_.get_service().get_option(impl_.get_implementation(), option, ec);
899  ASIO_SYNC_OP_VOID_RETURN(ec);
900  }
901 
903 
922  template <typename IoControlCommand>
923  void io_control(IoControlCommand& command)
924  {
925  asio::error_code ec;
926  impl_.get_service().io_control(impl_.get_implementation(), command, ec);
927  asio::detail::throw_error(ec, "io_control");
928  }
929 
931 
955  template <typename IoControlCommand>
956  ASIO_SYNC_OP_VOID io_control(IoControlCommand& command,
957  asio::error_code& ec)
958  {
959  impl_.get_service().io_control(impl_.get_implementation(), command, ec);
960  ASIO_SYNC_OP_VOID_RETURN(ec);
961  }
962 
964 
974  bool non_blocking() const
975  {
976  return impl_.get_service().non_blocking(impl_.get_implementation());
977  }
978 
980 
992  void non_blocking(bool mode)
993  {
994  asio::error_code ec;
995  impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec);
996  asio::detail::throw_error(ec, "non_blocking");
997  }
998 
1000 
1012  ASIO_SYNC_OP_VOID non_blocking(
1013  bool mode, asio::error_code& ec)
1014  {
1015  impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec);
1016  ASIO_SYNC_OP_VOID_RETURN(ec);
1017  }
1018 
1020 
1033  bool native_non_blocking() const
1034  {
1035  return impl_.get_service().native_non_blocking(impl_.get_implementation());
1036  }
1037 
1039 
1053  void native_non_blocking(bool mode)
1054  {
1055  asio::error_code ec;
1056  impl_.get_service().native_non_blocking(
1057  impl_.get_implementation(), mode, ec);
1058  asio::detail::throw_error(ec, "native_non_blocking");
1059  }
1060 
1062 
1076  ASIO_SYNC_OP_VOID native_non_blocking(
1077  bool mode, asio::error_code& ec)
1078  {
1079  impl_.get_service().native_non_blocking(
1080  impl_.get_implementation(), mode, ec);
1081  ASIO_SYNC_OP_VOID_RETURN(ec);
1082  }
1083 
1085 
1099  endpoint_type local_endpoint() const
1100  {
1101  asio::error_code ec;
1102  endpoint_type ep = impl_.get_service().local_endpoint(
1103  impl_.get_implementation(), ec);
1104  asio::detail::throw_error(ec, "local_endpoint");
1105  return ep;
1106  }
1107 
1109 
1130  endpoint_type local_endpoint(asio::error_code& ec) const
1131  {
1132  return impl_.get_service().local_endpoint(impl_.get_implementation(), ec);
1133  }
1134 
1137 
1151  void wait(wait_type w)
1152  {
1153  asio::error_code ec;
1154  impl_.get_service().wait(impl_.get_implementation(), w, ec);
1155  asio::detail::throw_error(ec, "wait");
1156  }
1157 
1160 
1177  ASIO_SYNC_OP_VOID wait(wait_type w, asio::error_code& ec)
1178  {
1179  impl_.get_service().wait(impl_.get_implementation(), w, ec);
1180  ASIO_SYNC_OP_VOID_RETURN(ec);
1181  }
1182 
1185 
1221  template <
1222  ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))
1223  WaitHandler ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
1224  ASIO_INITFN_AUTO_RESULT_TYPE(WaitHandler,
1225  void (asio::error_code))
1226  async_wait(wait_type w,
1227  ASIO_MOVE_ARG(WaitHandler) handler
1228  ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
1229  {
1230  return async_initiate<WaitHandler, void (asio::error_code)>(
1231  initiate_async_wait(this), handler, w);
1232  }
1233 
1234 #if !defined(ASIO_NO_EXTENSIONS)
1235 
1253  template <typename Protocol1, typename Executor1>
1255  typename enable_if<
1256  is_convertible<Protocol, Protocol1>::value
1257  >::type* = 0)
1258  {
1259  asio::error_code ec;
1260  impl_.get_service().accept(impl_.get_implementation(),
1261  peer, static_cast<endpoint_type*>(0), ec);
1262  asio::detail::throw_error(ec, "accept");
1263  }
1264 
1266 
1288  template <typename Protocol1, typename Executor1>
1289  ASIO_SYNC_OP_VOID accept(
1291  typename enable_if<
1292  is_convertible<Protocol, Protocol1>::value
1293  >::type* = 0)
1294  {
1295  impl_.get_service().accept(impl_.get_implementation(),
1296  peer, static_cast<endpoint_type*>(0), ec);
1297  ASIO_SYNC_OP_VOID_RETURN(ec);
1298  }
1299 
1301 
1338  template <typename Protocol1, typename Executor1,
1339  ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))
1340  AcceptHandler ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
1341  ASIO_INITFN_AUTO_RESULT_TYPE(AcceptHandler,
1342  void (asio::error_code))
1343  async_accept(basic_socket<Protocol1, Executor1>& peer,
1344  ASIO_MOVE_ARG(AcceptHandler) handler
1345  ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
1346  typename enable_if<
1347  is_convertible<Protocol, Protocol1>::value
1348  >::type* = 0)
1349  {
1350  return async_initiate<AcceptHandler, void (asio::error_code)>(
1351  initiate_async_accept(this), handler,
1352  &peer, static_cast<endpoint_type*>(0));
1353  }
1354 
1356 
1378  template <typename Executor1>
1380  endpoint_type& peer_endpoint)
1381  {
1382  asio::error_code ec;
1383  impl_.get_service().accept(impl_.get_implementation(),
1384  peer, &peer_endpoint, ec);
1385  asio::detail::throw_error(ec, "accept");
1386  }
1387 
1389 
1416  template <typename Executor1>
1417  ASIO_SYNC_OP_VOID accept(basic_socket<protocol_type, Executor1>& peer,
1418  endpoint_type& peer_endpoint, asio::error_code& ec)
1419  {
1420  impl_.get_service().accept(
1421  impl_.get_implementation(), peer, &peer_endpoint, ec);
1422  ASIO_SYNC_OP_VOID_RETURN(ec);
1423  }
1424 
1426 
1451  template <typename Executor1,
1452  ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))
1453  AcceptHandler ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
1454  ASIO_INITFN_AUTO_RESULT_TYPE(AcceptHandler,
1455  void (asio::error_code))
1456  async_accept(basic_socket<protocol_type, Executor1>& peer,
1457  endpoint_type& peer_endpoint,
1458  ASIO_MOVE_ARG(AcceptHandler) handler
1459  ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
1460  {
1461  return async_initiate<AcceptHandler, void (asio::error_code)>(
1462  initiate_async_accept(this), handler, &peer, &peer_endpoint);
1463  }
1464 #endif // !defined(ASIO_NO_EXTENSIONS)
1465 
1466 #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
1467 
1487  typename Protocol::socket::template rebind_executor<executor_type>::other
1488  accept()
1489  {
1490  asio::error_code ec;
1491  typename Protocol::socket::template rebind_executor<
1492  executor_type>::other peer(impl_.get_executor());
1493  impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
1494  asio::detail::throw_error(ec, "accept");
1495  return peer;
1496  }
1497 
1499 
1523  typename Protocol::socket::template rebind_executor<executor_type>::other
1525  {
1526  typename Protocol::socket::template rebind_executor<
1527  executor_type>::other peer(impl_.get_executor());
1528  impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
1529  return peer;
1530  }
1531 
1533 
1573  template <
1574  ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
1575  typename Protocol::socket::template rebind_executor<
1576  executor_type>::other)) MoveAcceptHandler
1577  ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
1578  ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,
1579  void (asio::error_code,
1580  typename Protocol::socket::template
1582  async_accept(
1583  ASIO_MOVE_ARG(MoveAcceptHandler) handler
1584  ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
1585  {
1586  return async_initiate<MoveAcceptHandler,
1587  void (asio::error_code, typename Protocol::socket::template
1588  rebind_executor<executor_type>::other)>(
1589  initiate_async_move_accept(this), handler,
1590  impl_.get_executor(), static_cast<endpoint_type*>(0),
1591  static_cast<typename Protocol::socket::template
1592  rebind_executor<executor_type>::other*>(0));
1593  }
1594 
1596 
1618  template <typename Executor1>
1619  typename Protocol::socket::template rebind_executor<Executor1>::other
1620  accept(const Executor1& ex,
1621  typename enable_if<
1624  >::type* = 0)
1625  {
1626  asio::error_code ec;
1627  typename Protocol::socket::template
1629  impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
1630  asio::detail::throw_error(ec, "accept");
1631  return peer;
1632  }
1633 
1635 
1657  template <typename ExecutionContext>
1658  typename Protocol::socket::template rebind_executor<
1659  typename ExecutionContext::executor_type>::other
1660  accept(ExecutionContext& context,
1661  typename enable_if<
1662  is_convertible<ExecutionContext&, execution_context&>::value
1663  >::type* = 0)
1664  {
1665  asio::error_code ec;
1666  typename Protocol::socket::template rebind_executor<
1667  typename ExecutionContext::executor_type>::other peer(context);
1668  impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
1669  asio::detail::throw_error(ec, "accept");
1670  return peer;
1671  }
1672 
1674 
1701  template <typename Executor1>
1702  typename Protocol::socket::template rebind_executor<Executor1>::other
1703  accept(const Executor1& ex, asio::error_code& ec,
1704  typename enable_if<
1707  >::type* = 0)
1708  {
1709  typename Protocol::socket::template
1711  impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
1712  return peer;
1713  }
1714 
1716 
1743  template <typename ExecutionContext>
1744  typename Protocol::socket::template rebind_executor<
1745  typename ExecutionContext::executor_type>::other
1746  accept(ExecutionContext& context, asio::error_code& ec,
1747  typename enable_if<
1748  is_convertible<ExecutionContext&, execution_context&>::value
1749  >::type* = 0)
1750  {
1751  typename Protocol::socket::template rebind_executor<
1752  typename ExecutionContext::executor_type>::other peer(context);
1753  impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
1754  return peer;
1755  }
1756 
1758 
1799  template <typename Executor1,
1800  ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
1801  typename Protocol::socket::template rebind_executor<
1802  Executor1>::other)) MoveAcceptHandler
1803  ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
1804  ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,
1805  void (asio::error_code,
1806  typename Protocol::socket::template rebind_executor<
1807  Executor1>::other))
1808  async_accept(const Executor1& ex,
1809  ASIO_MOVE_ARG(MoveAcceptHandler) handler
1810  ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
1811  typename enable_if<
1814  >::type* = 0)
1815  {
1816  typedef typename Protocol::socket::template rebind_executor<
1817  Executor1>::other other_socket_type;
1818 
1819  return async_initiate<MoveAcceptHandler,
1820  void (asio::error_code, other_socket_type)>(
1821  initiate_async_move_accept(this), handler,
1822  ex, static_cast<endpoint_type*>(0),
1823  static_cast<other_socket_type*>(0));
1824  }
1825 
1827 
1869  template <typename ExecutionContext,
1870  ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
1871  typename Protocol::socket::template rebind_executor<
1872  typename ExecutionContext::executor_type>::other)) MoveAcceptHandler
1873  ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
1874  ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,
1875  void (asio::error_code,
1876  typename Protocol::socket::template rebind_executor<
1877  typename ExecutionContext::executor_type>::other))
1878  async_accept(ExecutionContext& context,
1879  ASIO_MOVE_ARG(MoveAcceptHandler) handler
1880  ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
1881  typename enable_if<
1882  is_convertible<ExecutionContext&, execution_context&>::value
1883  >::type* = 0)
1884  {
1885  typedef typename Protocol::socket::template rebind_executor<
1886  typename ExecutionContext::executor_type>::other other_socket_type;
1887 
1888  return async_initiate<MoveAcceptHandler,
1889  void (asio::error_code, other_socket_type)>(
1890  initiate_async_move_accept(this), handler,
1891  context.get_executor(), static_cast<endpoint_type*>(0),
1892  static_cast<other_socket_type*>(0));
1893  }
1894 
1896 
1919  typename Protocol::socket::template rebind_executor<executor_type>::other
1920  accept(endpoint_type& peer_endpoint)
1921  {
1922  asio::error_code ec;
1923  typename Protocol::socket::template rebind_executor<
1924  executor_type>::other peer(impl_.get_executor());
1925  impl_.get_service().accept(impl_.get_implementation(),
1926  peer, &peer_endpoint, ec);
1927  asio::detail::throw_error(ec, "accept");
1928  return peer;
1929  }
1930 
1932 
1960  typename Protocol::socket::template rebind_executor<executor_type>::other
1961  accept(endpoint_type& peer_endpoint, asio::error_code& ec)
1962  {
1963  typename Protocol::socket::template rebind_executor<
1964  executor_type>::other peer(impl_.get_executor());
1965  impl_.get_service().accept(impl_.get_implementation(),
1966  peer, &peer_endpoint, ec);
1967  return peer;
1968  }
1969 
1971 
2017  template <
2018  ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
2019  typename Protocol::socket::template rebind_executor<
2020  executor_type>::other)) MoveAcceptHandler
2021  ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
2022  ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,
2023  void (asio::error_code,
2024  typename Protocol::socket::template
2025  rebind_executor<executor_type>::other))
2026  async_accept(endpoint_type& peer_endpoint,
2027  ASIO_MOVE_ARG(MoveAcceptHandler) handler
2028  ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
2029  {
2030  return async_initiate<MoveAcceptHandler,
2031  void (asio::error_code, typename Protocol::socket::template
2032  rebind_executor<executor_type>::other)>(
2033  initiate_async_move_accept(this), handler,
2034  impl_.get_executor(), &peer_endpoint,
2035  static_cast<typename Protocol::socket::template
2036  rebind_executor<executor_type>::other*>(0));
2037  }
2038 
2040 
2067  template <typename Executor1>
2068  typename Protocol::socket::template rebind_executor<Executor1>::other
2069  accept(const Executor1& ex, endpoint_type& peer_endpoint,
2070  typename enable_if<
2073  >::type* = 0)
2074  {
2075  asio::error_code ec;
2076  typename Protocol::socket::template
2078  impl_.get_service().accept(impl_.get_implementation(),
2079  peer, &peer_endpoint, ec);
2080  asio::detail::throw_error(ec, "accept");
2081  return peer;
2082  }
2083 
2085 
2112  template <typename ExecutionContext>
2113  typename Protocol::socket::template rebind_executor<
2114  typename ExecutionContext::executor_type>::other
2115  accept(ExecutionContext& context, endpoint_type& peer_endpoint,
2116  typename enable_if<
2117  is_convertible<ExecutionContext&, execution_context&>::value
2118  >::type* = 0)
2119  {
2120  asio::error_code ec;
2121  typename Protocol::socket::template rebind_executor<
2122  typename ExecutionContext::executor_type>::other peer(context);
2123  impl_.get_service().accept(impl_.get_implementation(),
2124  peer, &peer_endpoint, ec);
2125  asio::detail::throw_error(ec, "accept");
2126  return peer;
2127  }
2128 
2130 
2162  template <typename Executor1>
2163  typename Protocol::socket::template rebind_executor<Executor1>::other
2164  accept(const executor_type& ex,
2165  endpoint_type& peer_endpoint, asio::error_code& ec,
2166  typename enable_if<
2169  >::type* = 0)
2170  {
2171  typename Protocol::socket::template
2173  impl_.get_service().accept(impl_.get_implementation(),
2174  peer, &peer_endpoint, ec);
2175  return peer;
2176  }
2177 
2179 
2211  template <typename ExecutionContext>
2212  typename Protocol::socket::template rebind_executor<
2213  typename ExecutionContext::executor_type>::other
2214  accept(ExecutionContext& context,
2215  endpoint_type& peer_endpoint, asio::error_code& ec,
2216  typename enable_if<
2217  is_convertible<ExecutionContext&, execution_context&>::value
2218  >::type* = 0)
2219  {
2220  typename Protocol::socket::template rebind_executor<
2221  typename ExecutionContext::executor_type>::other peer(context);
2222  impl_.get_service().accept(impl_.get_implementation(),
2223  peer, &peer_endpoint, ec);
2224  return peer;
2225  }
2226 
2228 
2275  template <typename Executor1,
2276  ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
2277  typename Protocol::socket::template rebind_executor<
2278  Executor1>::other)) MoveAcceptHandler
2279  ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
2280  ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,
2281  void (asio::error_code,
2282  typename Protocol::socket::template rebind_executor<
2283  Executor1>::other))
2284  async_accept(const Executor1& ex, endpoint_type& peer_endpoint,
2285  ASIO_MOVE_ARG(MoveAcceptHandler) handler
2286  ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
2287  typename enable_if<
2290  >::type* = 0)
2291  {
2292  typedef typename Protocol::socket::template rebind_executor<
2293  Executor1>::other other_socket_type;
2294 
2295  return async_initiate<MoveAcceptHandler,
2296  void (asio::error_code, other_socket_type)>(
2297  initiate_async_move_accept(this), handler,
2298  ex, &peer_endpoint,
2299  static_cast<other_socket_type*>(0));
2300  }
2301 
2303 
2351  template <typename ExecutionContext,
2352  ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
2353  typename Protocol::socket::template rebind_executor<
2354  typename ExecutionContext::executor_type>::other)) MoveAcceptHandler
2355  ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
2356  ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,
2357  void (asio::error_code,
2358  typename Protocol::socket::template rebind_executor<
2359  typename ExecutionContext::executor_type>::other))
2360  async_accept(ExecutionContext& context,
2361  endpoint_type& peer_endpoint,
2362  ASIO_MOVE_ARG(MoveAcceptHandler) handler
2363  ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
2364  typename enable_if<
2365  is_convertible<ExecutionContext&, execution_context&>::value
2366  >::type* = 0)
2367  {
2368  typedef typename Protocol::socket::template rebind_executor<
2369  typename ExecutionContext::executor_type>::other other_socket_type;
2370 
2371  return async_initiate<MoveAcceptHandler,
2372  void (asio::error_code, other_socket_type)>(
2373  initiate_async_move_accept(this), handler,
2374  context.get_executor(), &peer_endpoint,
2375  static_cast<other_socket_type*>(0));
2376  }
2377 #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
2378 
2379 private:
2380  // Disallow copying and assignment.
2381  basic_socket_acceptor(const basic_socket_acceptor&) ASIO_DELETED;
2382  basic_socket_acceptor& operator=(
2383  const basic_socket_acceptor&) ASIO_DELETED;
2384 
2385  class initiate_async_wait
2386  {
2387  public:
2388  typedef Executor executor_type;
2389 
2390  explicit initiate_async_wait(basic_socket_acceptor* self)
2391  : self_(self)
2392  {
2393  }
2394 
2395  executor_type get_executor() const ASIO_NOEXCEPT
2396  {
2397  return self_->get_executor();
2398  }
2399 
2400  template <typename WaitHandler>
2401  void operator()(ASIO_MOVE_ARG(WaitHandler) handler, wait_type w) const
2402  {
2403  // If you get an error on the following line it means that your handler
2404  // does not meet the documented type requirements for a WaitHandler.
2405  ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
2406 
2407  detail::non_const_lvalue<WaitHandler> handler2(handler);
2408  self_->impl_.get_service().async_wait(
2409  self_->impl_.get_implementation(), w,
2410  handler2.value, self_->impl_.get_executor());
2411  }
2412 
2413  private:
2414  basic_socket_acceptor* self_;
2415  };
2416 
2417  class initiate_async_accept
2418  {
2419  public:
2420  typedef Executor executor_type;
2421 
2422  explicit initiate_async_accept(basic_socket_acceptor* self)
2423  : self_(self)
2424  {
2425  }
2426 
2427  executor_type get_executor() const ASIO_NOEXCEPT
2428  {
2429  return self_->get_executor();
2430  }
2431 
2432  template <typename AcceptHandler, typename Protocol1, typename Executor1>
2433  void operator()(ASIO_MOVE_ARG(AcceptHandler) handler,
2435  endpoint_type* peer_endpoint) const
2436  {
2437  // If you get an error on the following line it means that your handler
2438  // does not meet the documented type requirements for a AcceptHandler.
2439  ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check;
2440 
2441  detail::non_const_lvalue<AcceptHandler> handler2(handler);
2442  self_->impl_.get_service().async_accept(
2443  self_->impl_.get_implementation(), *peer, peer_endpoint,
2444  handler2.value, self_->impl_.get_executor());
2445  }
2446 
2447  private:
2448  basic_socket_acceptor* self_;
2449  };
2450 
2451  class initiate_async_move_accept
2452  {
2453  public:
2454  typedef Executor executor_type;
2455 
2456  explicit initiate_async_move_accept(basic_socket_acceptor* self)
2457  : self_(self)
2458  {
2459  }
2460 
2461  executor_type get_executor() const ASIO_NOEXCEPT
2462  {
2463  return self_->get_executor();
2464  }
2465 
2466  template <typename MoveAcceptHandler, typename Executor1, typename Socket>
2467  void operator()(ASIO_MOVE_ARG(MoveAcceptHandler) handler,
2468  const Executor1& peer_ex, endpoint_type* peer_endpoint, Socket*) const
2469  {
2470  // If you get an error on the following line it means that your handler
2471  // does not meet the documented type requirements for a MoveAcceptHandler.
2472  ASIO_MOVE_ACCEPT_HANDLER_CHECK(
2473  MoveAcceptHandler, handler, Socket) type_check;
2474 
2476  self_->impl_.get_service().async_move_accept(
2477  self_->impl_.get_implementation(), peer_ex, peer_endpoint,
2478  handler2.value, self_->impl_.get_executor());
2479  }
2480 
2481  private:
2482  basic_socket_acceptor* self_;
2483  };
2484 
2485 #if defined(ASIO_WINDOWS_RUNTIME)
2487  detail::null_socket_service<Protocol>, Executor> impl_;
2488 #elif defined(ASIO_HAS_IOCP)
2490  detail::win_iocp_socket_service<Protocol>, Executor> impl_;
2491 #else
2494 #endif
2495 };
2496 
2497 } // namespace asio
2498 
2499 #include "asio/detail/pop_options.hpp"
2500 
2501 #endif // ASIO_BASIC_SOCKET_ACCEPTOR_HPP
asio::detail::socket_option::boolean< ASIO_OS_DEF(SOL_SOCKET), ASIO_OS_DEF(SO_REUSEADDR)> reuse_address
Socket option to allow the socket to be bound to an address that is already in use.
Definition: socket_base.hpp:396
detail::reactive_socket_service< Protocol >::native_handle_type native_handle_type
The native representation of an acceptor.
Definition: basic_socket_acceptor.hpp:102
void accept(basic_socket< Protocol1, Executor1 > &peer, typename enable_if< is_convertible< Protocol, Protocol1 >::value >::type *=0)
Accept a new connection.
Definition: basic_socket_acceptor.hpp:1254
ASIO_SYNC_OP_VOID set_option(const SettableSocketOption &option, asio::error_code &ec)
Set an option on the acceptor.
Definition: basic_socket_acceptor.hpp:830
basic_socket_acceptor(const executor_type &ex)
Construct an acceptor without opening it.
Definition: basic_socket_acceptor.hpp:121
ASIO_SYNC_OP_VOID non_blocking(bool mode, asio::error_code &ec)
Sets the non-blocking mode of the acceptor.
Definition: basic_socket_acceptor.hpp:1012
void native_non_blocking(bool mode)
Sets the non-blocking mode of the native acceptor implementation.
Definition: basic_socket_acceptor.hpp:1053
basic_socket_acceptor(const executor_type &ex, const protocol_type &protocol)
Construct an open acceptor.
Definition: basic_socket_acceptor.hpp:157
The socket_base class is used as a base for the basic_stream_socket and basic_datagram_socket class t...
Definition: socket_base.hpp:30
void close()
Close the acceptor.
Definition: basic_socket_acceptor.hpp:647
void set_option(const SettableSocketOption &option)
Set an option on the acceptor.
Definition: basic_socket_acceptor.hpp:796
ASIO_SYNC_OP_VOID close(asio::error_code &ec)
Close the acceptor.
Definition: basic_socket_acceptor.hpp:676
Definition: blocking.hpp:208
basic_socket_acceptor(const executor_type &ex, const protocol_type &protocol, const native_handle_type &native_acceptor)
Construct a basic_socket_acceptor on an existing native acceptor.
Definition: basic_socket_acceptor.hpp:305
endpoint_type local_endpoint(asio::error_code &ec) const
Get the local endpoint of the acceptor.
Definition: basic_socket_acceptor.hpp:1130
wait_type
Wait types.
Definition: socket_base.hpp:82
basic_socket_acceptor(ExecutionContext &context, const endpoint_type &endpoint, bool reuse_addr=true, typename enable_if< is_convertible< ExecutionContext &, execution_context &>::value >::type *=0)
Construct an acceptor opened on the given endpoint.
Definition: basic_socket_acceptor.hpp:266
ASIO_INITFN_AUTO_RESULT_TYPE(WaitHandler, void(asio::error_code)) async_wait(wait_type w
Asynchronously wait for the acceptor to become ready to read, ready to write, or to have pending erro...
~basic_socket_acceptor()
Destroys the acceptor.
Definition: basic_socket_acceptor.hpp:435
ASIO_SYNC_OP_VOID open(const protocol_type &protocol, asio::error_code &ec)
Open the acceptor using the specified protocol.
Definition: basic_socket_acceptor.hpp:487
native_handle_type release()
Release ownership of the underlying native acceptor.
Definition: basic_socket_acceptor.hpp:701
basic_socket_acceptor< Protocol, Executor1 > other
The socket type when rebound to the specified executor.
Definition: basic_socket_acceptor.hpp:88
void assign(const protocol_type &protocol, const native_handle_type &native_acceptor)
Assigns an existing native acceptor to the acceptor.
Definition: basic_socket_acceptor.hpp:504
endpoint_type local_endpoint() const
Get the local endpoint of the acceptor.
Definition: basic_socket_acceptor.hpp:1099
ASIO_SYNC_OP_VOID listen(int backlog, asio::error_code &ec)
Place the acceptor into the state where it will listen for new connections.
Definition: basic_socket_acceptor.hpp:631
ASIO_SYNC_OP_VOID bind(const endpoint_type &endpoint, asio::error_code &ec)
Bind the acceptor to the given local endpoint.
Definition: basic_socket_acceptor.hpp:585
basic_socket_acceptor(ExecutionContext &context, const protocol_type &protocol, typename enable_if< is_convertible< ExecutionContext &, execution_context &>::value >::type *=0)
Construct an open acceptor.
Definition: basic_socket_acceptor.hpp:178
Provides the ability to accept new connections.
Definition: basic_socket_acceptor.hpp:51
Executor executor_type
The type of the executor associated with the object.
Definition: basic_socket_acceptor.hpp:81
native_handle_type release(asio::error_code &ec)
Release ownership of the underlying native acceptor.
Definition: basic_socket_acceptor.hpp:729
ASIO_SYNC_OP_VOID native_non_blocking(bool mode, asio::error_code &ec)
Sets the non-blocking mode of the native acceptor implementation.
Definition: basic_socket_acceptor.hpp:1076
Definition: getopt.h:41
void listen(int backlog=socket_base::max_listen_connections)
Place the acceptor into the state where it will listen for new connections.
Definition: basic_socket_acceptor.hpp:602
Rebinds the acceptor type to another executor.
Definition: basic_socket_acceptor.hpp:85
ASIO_SYNC_OP_VOID assign(const protocol_type &protocol, const native_handle_type &native_acceptor, asio::error_code &ec)
Assigns an existing native acceptor to the acceptor.
Definition: basic_socket_acceptor.hpp:523
bool non_blocking() const
Gets the non-blocking mode of the acceptor.
Definition: basic_socket_acceptor.hpp:974
Definition: type_traits.hpp:97
ASIO_SYNC_OP_VOID cancel(asio::error_code &ec)
Cancel all asynchronous operations associated with the acceptor.
Definition: basic_socket_acceptor.hpp:768
Definition: non_const_lvalue.hpp:27
ASIO_SYNC_OP_VOID wait(wait_type w, asio::error_code &ec)
Wait for the acceptor to become ready to read, ready to write, or to have pending error conditions...
Definition: basic_socket_acceptor.hpp:1177
The is_executor trait detects whether a type T meets the Executor type requirements.
Definition: is_executor.hpp:33
void bind(const endpoint_type &endpoint)
Bind the acceptor to the given local endpoint.
Definition: basic_socket_acceptor.hpp:555
native_handle_type native_handle()
Get the native acceptor representation.
Definition: basic_socket_acceptor.hpp:740
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)
Construct a basic_socket_acceptor on an existing native acceptor.
Definition: basic_socket_acceptor.hpp:331
Protocol::endpoint endpoint_type
The endpoint type.
Definition: basic_socket_acceptor.hpp:109
Class to represent an error code value.
Definition: error_code.hpp:80
Definition: io_object_impl.hpp:33
void wait(wait_type w)
Wait for the acceptor to become ready to read, ready to write, or to have pending error conditions...
Definition: basic_socket_acceptor.hpp:1151
basic_socket_acceptor(const executor_type &ex, const endpoint_type &endpoint, bool reuse_addr=true)
Construct an acceptor opened on the given endpoint.
Definition: basic_socket_acceptor.hpp:217
void cancel()
Cancel all asynchronous operations associated with the acceptor.
Definition: basic_socket_acceptor.hpp:753
Definition: reactive_socket_service.hpp:47
void io_control(IoControlCommand &command)
Perform an IO control command on the acceptor.
Definition: basic_socket_acceptor.hpp:923
void get_option(GettableSocketOption &option) const
Get an option from the acceptor.
Definition: basic_socket_acceptor.hpp:860
bool native_non_blocking() const
Gets the non-blocking mode of the native acceptor implementation.
Definition: basic_socket_acceptor.hpp:1033
Provides socket functionality.
Definition: basic_socket.hpp:52
basic_socket_acceptor(ExecutionContext &context, typename enable_if< is_convertible< ExecutionContext &, execution_context &>::value >::type *=0)
Construct an acceptor without opening it.
Definition: basic_socket_acceptor.hpp:137
ASIO_SYNC_OP_VOID accept(basic_socket< Protocol1, Executor1 > &peer, asio::error_code &ec, typename enable_if< is_convertible< Protocol, Protocol1 >::value >::type *=0)
Accept a new connection.
Definition: basic_socket_acceptor.hpp:1289
ASIO_SYNC_OP_VOID get_option(GettableSocketOption &option, asio::error_code &ec) const
Get an option from the acceptor.
Definition: basic_socket_acceptor.hpp:895
Protocol protocol_type
The protocol type.
Definition: basic_socket_acceptor.hpp:106
void non_blocking(bool mode)
Sets the non-blocking mode of the acceptor.
Definition: basic_socket_acceptor.hpp:992
Definition: any_io_executor.hpp:28
bool is_open() const
Determine whether the acceptor is open.
Definition: basic_socket_acceptor.hpp:532
executor_type get_executor() ASIO_NOEXCEPT
Get the executor associated with the object.
Definition: basic_socket_acceptor.hpp:440
ASIO_SYNC_OP_VOID io_control(IoControlCommand &command, asio::error_code &ec)
Perform an IO control command on the acceptor.
Definition: basic_socket_acceptor.hpp:956
void open(const protocol_type &protocol=protocol_type())
Open the acceptor using the specified protocol.
Definition: basic_socket_acceptor.hpp:460
void assign(int v, const error_category &c)
Assign a new error value.
Definition: error_code.hpp:112
The is_executor trait detects whether a type T satisfies the execution::executor concept.
Definition: executor.hpp:109