Home | History | Annotate | Download | only in asio
      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 
     25 namespace asio {
     26 
     27 /// Default service implementation for a socket acceptor.
     28 template <typename Protocol>
     29 class socket_acceptor_service
     30   : public asio::detail::service_base<socket_acceptor_service<Protocol> >
     31 {
     32 public:
     33 
     34   /// The protocol type.
     35   typedef Protocol protocol_type;
     36 
     37   /// The endpoint type.
     38   typedef typename protocol_type::endpoint endpoint_type;
     39 
     40 private:
     41   // The type of the platform-specific implementation.
     42   typedef detail::reactive_socket_service<Protocol> service_impl_type;
     43 
     44 public:
     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 
    250 private:
    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