1//
2// socket_acceptor_service.hpp
3// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
4//
5// Copyright (c) 2003-2015 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_SOCKET_ACCEPTOR_SERVICE_HPP
12#define ASIO_SOCKET_ACCEPTOR_SERVICE_HPP
13
14
15#include "asio/detail/config.hpp"
16#include "asio/basic_socket.hpp"
17#include "asio/detail/type_traits.hpp"
18#include "asio/error.hpp"
19#include "asio/io_service.hpp"
20
21# include "asio/detail/reactive_socket_service.hpp"
22
23#include "asio/detail/push_options.hpp"
24
25namespace asio {
26
27/// Default service implementation for a socket acceptor.
28template <typename Protocol>
29class socket_acceptor_service
30  : public asio::detail::service_base<socket_acceptor_service<Protocol> >
31{
32public:
33
34  /// The protocol type.
35  typedef Protocol protocol_type;
36
37  /// The endpoint type.
38  typedef typename protocol_type::endpoint endpoint_type;
39
40private:
41  // The type of the platform-specific implementation.
42  typedef detail::reactive_socket_service<Protocol> service_impl_type;
43
44public:
45  /// The native type of the socket acceptor.
46  typedef typename service_impl_type::implementation_type implementation_type;
47
48  /// (Deprecated: Use native_handle_type.) The native acceptor type.
49  typedef typename service_impl_type::native_handle_type native_type;
50
51  /// The native acceptor type.
52  typedef typename service_impl_type::native_handle_type native_handle_type;
53
54  /// Construct a new socket acceptor service for the specified io_service.
55  explicit socket_acceptor_service(asio::io_service& io_service)
56    : asio::detail::service_base<
57        socket_acceptor_service<Protocol> >(io_service),
58      service_impl_(io_service)
59  {
60  }
61
62  /// Construct a new socket acceptor implementation.
63  void construct(implementation_type& impl)
64  {
65    service_impl_.construct(impl);
66  }
67
68  /// Move-construct a new socket acceptor implementation.
69  void move_construct(implementation_type& impl,
70      implementation_type& other_impl)
71  {
72    service_impl_.move_construct(impl, other_impl);
73  }
74
75  /// Move-assign from another socket acceptor implementation.
76  void move_assign(implementation_type& impl,
77      socket_acceptor_service& other_service,
78      implementation_type& other_impl)
79  {
80    service_impl_.move_assign(impl, other_service.service_impl_, other_impl);
81  }
82
83  /// Move-construct a new socket acceptor implementation from another protocol
84  /// type.
85  template <typename Protocol1>
86  void converting_move_construct(implementation_type& impl,
87      typename socket_acceptor_service<
88        Protocol1>::implementation_type& other_impl,
89      typename enable_if<is_convertible<
90        Protocol1, Protocol>::value>::type* = 0)
91  {
92    service_impl_.template converting_move_construct<Protocol1>(
93        impl, other_impl);
94  }
95
96  /// Destroy a socket acceptor implementation.
97  void destroy(implementation_type& impl)
98  {
99    service_impl_.destroy(impl);
100  }
101
102  /// Open a new socket acceptor implementation.
103  asio::error_code open(implementation_type& impl,
104      const protocol_type& protocol, asio::error_code& ec)
105  {
106    return service_impl_.open(impl, protocol, ec);
107  }
108
109  /// Assign an existing native acceptor to a socket acceptor.
110  asio::error_code assign(implementation_type& impl,
111      const protocol_type& protocol, const native_handle_type& native_acceptor,
112      asio::error_code& ec)
113  {
114    return service_impl_.assign(impl, protocol, native_acceptor, ec);
115  }
116
117  /// Determine whether the acceptor is open.
118  bool is_open(const implementation_type& impl) const
119  {
120    return service_impl_.is_open(impl);
121  }
122
123  /// Cancel all asynchronous operations associated with the acceptor.
124  asio::error_code cancel(implementation_type& impl,
125      asio::error_code& ec)
126  {
127    return service_impl_.cancel(impl, ec);
128  }
129
130  /// Bind the socket acceptor to the specified local endpoint.
131  asio::error_code bind(implementation_type& impl,
132      const endpoint_type& endpoint, asio::error_code& ec)
133  {
134    return service_impl_.bind(impl, endpoint, ec);
135  }
136
137  /// Place the socket acceptor into the state where it will listen for new
138  /// connections.
139  asio::error_code listen(implementation_type& impl, int backlog,
140      asio::error_code& ec)
141  {
142    return service_impl_.listen(impl, backlog, ec);
143  }
144
145  /// Close a socket acceptor implementation.
146  asio::error_code close(implementation_type& impl,
147      asio::error_code& ec)
148  {
149    return service_impl_.close(impl, ec);
150  }
151
152  /// (Deprecated: Use native_handle().) Get the native acceptor implementation.
153  native_type native(implementation_type& impl)
154  {
155    return service_impl_.native_handle(impl);
156  }
157
158  /// Get the native acceptor implementation.
159  native_handle_type native_handle(implementation_type& impl)
160  {
161    return service_impl_.native_handle(impl);
162  }
163
164  /// Set a socket option.
165  template <typename SettableSocketOption>
166  asio::error_code set_option(implementation_type& impl,
167      const SettableSocketOption& option, asio::error_code& ec)
168  {
169    return service_impl_.set_option(impl, option, ec);
170  }
171
172  /// Get a socket option.
173  template <typename GettableSocketOption>
174  asio::error_code get_option(const implementation_type& impl,
175      GettableSocketOption& option, asio::error_code& ec) const
176  {
177    return service_impl_.get_option(impl, option, ec);
178  }
179
180  /// Perform an IO control command on the socket.
181  template <typename IoControlCommand>
182  asio::error_code io_control(implementation_type& impl,
183      IoControlCommand& command, asio::error_code& ec)
184  {
185    return service_impl_.io_control(impl, command, ec);
186  }
187
188  /// Gets the non-blocking mode of the acceptor.
189  bool non_blocking(const implementation_type& impl) const
190  {
191    return service_impl_.non_blocking(impl);
192  }
193
194  /// Sets the non-blocking mode of the acceptor.
195  asio::error_code non_blocking(implementation_type& impl,
196      bool mode, asio::error_code& ec)
197  {
198    return service_impl_.non_blocking(impl, mode, ec);
199  }
200
201  /// Gets the non-blocking mode of the native acceptor implementation.
202  bool native_non_blocking(const implementation_type& impl) const
203  {
204    return service_impl_.native_non_blocking(impl);
205  }
206
207  /// Sets the non-blocking mode of the native acceptor implementation.
208  asio::error_code native_non_blocking(implementation_type& impl,
209      bool mode, asio::error_code& ec)
210  {
211    return service_impl_.native_non_blocking(impl, mode, ec);
212  }
213
214  /// Get the local endpoint.
215  endpoint_type local_endpoint(const implementation_type& impl,
216      asio::error_code& ec) const
217  {
218    return service_impl_.local_endpoint(impl, ec);
219  }
220
221  /// Accept a new connection.
222  template <typename Protocol1, typename SocketService>
223  asio::error_code accept(implementation_type& impl,
224      basic_socket<Protocol1, SocketService>& peer,
225      endpoint_type* peer_endpoint, asio::error_code& ec,
226      typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
227  {
228    return service_impl_.accept(impl, peer, peer_endpoint, ec);
229  }
230
231  /// Start an asynchronous accept.
232  template <typename Protocol1, typename SocketService, typename AcceptHandler>
233  ASIO_INITFN_RESULT_TYPE(AcceptHandler,
234      void (asio::error_code))
235  async_accept(implementation_type& impl,
236      basic_socket<Protocol1, SocketService>& peer,
237      endpoint_type* peer_endpoint,
238      ASIO_MOVE_ARG(AcceptHandler) handler,
239      typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
240  {
241    detail::async_result_init<
242      AcceptHandler, void (asio::error_code)> init(
243        ASIO_MOVE_CAST(AcceptHandler)(handler));
244
245    service_impl_.async_accept(impl, peer, peer_endpoint, init.handler);
246
247    return init.result.get();
248  }
249
250private:
251  // Destroy all user-defined handler objects owned by the service.
252  void shutdown_service()
253  {
254    service_impl_.shutdown_service();
255  }
256
257  // The platform-specific implementation.
258  service_impl_type service_impl_;
259};
260
261} // namespace asio
262
263#include "asio/detail/pop_options.hpp"
264
265#endif // ASIO_SOCKET_ACCEPTOR_SERVICE_HPP
266