1 //
2 // waitable_timer_service.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2016 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_WAITABLE_TIMER_SERVICE_HPP
12 #define ASIO_WAITABLE_TIMER_SERVICE_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 <cstddef>
20 #include "asio/async_result.hpp"
21 #include "asio/detail/chrono_time_traits.hpp"
22 #include "asio/detail/deadline_timer_service.hpp"
23 #include "asio/io_service.hpp"
24 #include "asio/wait_traits.hpp"
25 
26 #include "asio/detail/push_options.hpp"
27 
28 namespace asio {
29 
30 /// Default service implementation for a timer.
31 template <typename Clock,
32     typename WaitTraits = asio::wait_traits<Clock> >
33 class waitable_timer_service
34 #if defined(GENERATING_DOCUMENTATION)
35   : public asio::io_service::service
36 #else
37   : public asio::detail::service_base<
38       waitable_timer_service<Clock, WaitTraits> >
39 #endif
40 {
41 public:
42 #if defined(GENERATING_DOCUMENTATION)
43   /// The unique service identifier.
44   static asio::io_service::id id;
45 #endif
46 
47   /// The clock type.
48   typedef Clock clock_type;
49 
50   /// The duration type of the clock.
51   typedef typename clock_type::duration duration;
52 
53   /// The time point type of the clock.
54   typedef typename clock_type::time_point time_point;
55 
56   /// The wait traits type.
57   typedef WaitTraits traits_type;
58 
59 private:
60   // The type of the platform-specific implementation.
61   typedef detail::deadline_timer_service<
62     detail::chrono_time_traits<Clock, WaitTraits> > service_impl_type;
63 
64 public:
65   /// The implementation type of the waitable timer.
66 #if defined(GENERATING_DOCUMENTATION)
67   typedef implementation_defined implementation_type;
68 #else
69   typedef typename service_impl_type::implementation_type implementation_type;
70 #endif
71 
72   /// Construct a new timer service for the specified io_service.
waitable_timer_service(asio::io_service & io_service)73   explicit waitable_timer_service(asio::io_service& io_service)
74     : asio::detail::service_base<
75         waitable_timer_service<Clock, WaitTraits> >(io_service),
76       service_impl_(io_service)
77   {
78   }
79 
80   /// Construct a new timer implementation.
construct(implementation_type & impl)81   void construct(implementation_type& impl)
82   {
83     service_impl_.construct(impl);
84   }
85 
86   /// Destroy a timer implementation.
destroy(implementation_type & impl)87   void destroy(implementation_type& impl)
88   {
89     service_impl_.destroy(impl);
90   }
91 
92   /// Cancel any asynchronous wait operations associated with the timer.
cancel(implementation_type & impl,asio::error_code & ec)93   std::size_t cancel(implementation_type& impl, asio::error_code& ec)
94   {
95     return service_impl_.cancel(impl, ec);
96   }
97 
98   /// Cancels one asynchronous wait operation associated with the timer.
cancel_one(implementation_type & impl,asio::error_code & ec)99   std::size_t cancel_one(implementation_type& impl,
100       asio::error_code& ec)
101   {
102     return service_impl_.cancel_one(impl, ec);
103   }
104 
105   /// Get the expiry time for the timer as an absolute time.
expires_at(const implementation_type & impl) const106   time_point expires_at(const implementation_type& impl) const
107   {
108     return service_impl_.expires_at(impl);
109   }
110 
111   /// Set the expiry time for the timer as an absolute time.
expires_at(implementation_type & impl,const time_point & expiry_time,asio::error_code & ec)112   std::size_t expires_at(implementation_type& impl,
113       const time_point& expiry_time, asio::error_code& ec)
114   {
115     return service_impl_.expires_at(impl, expiry_time, ec);
116   }
117 
118   /// Get the expiry time for the timer relative to now.
expires_from_now(const implementation_type & impl) const119   duration expires_from_now(const implementation_type& impl) const
120   {
121     return service_impl_.expires_from_now(impl);
122   }
123 
124   /// Set the expiry time for the timer relative to now.
expires_from_now(implementation_type & impl,const duration & expiry_time,asio::error_code & ec)125   std::size_t expires_from_now(implementation_type& impl,
126       const duration& expiry_time, asio::error_code& ec)
127   {
128     return service_impl_.expires_from_now(impl, expiry_time, ec);
129   }
130 
131   // Perform a blocking wait on the timer.
wait(implementation_type & impl,asio::error_code & ec)132   void wait(implementation_type& impl, asio::error_code& ec)
133   {
134     service_impl_.wait(impl, ec);
135   }
136 
137   // Start an asynchronous wait on the timer.
138   template <typename WaitHandler>
ASIO_INITFN_RESULT_TYPE(WaitHandler,void (asio::error_code))139   ASIO_INITFN_RESULT_TYPE(WaitHandler,
140       void (asio::error_code))
141   async_wait(implementation_type& impl,
142       ASIO_MOVE_ARG(WaitHandler) handler)
143   {
144     detail::async_result_init<
145       WaitHandler, void (asio::error_code)> init(
146         ASIO_MOVE_CAST(WaitHandler)(handler));
147 
148     service_impl_.async_wait(impl, init.handler);
149 
150     return init.result.get();
151   }
152 
153 private:
154   // Destroy all user-defined handler objects owned by the service.
shutdown_service()155   void shutdown_service()
156   {
157     service_impl_.shutdown_service();
158   }
159 
160   // The platform-specific implementation.
161   service_impl_type service_impl_;
162 };
163 
164 } // namespace asio
165 
166 #include "asio/detail/pop_options.hpp"
167 
168 #endif // ASIO_WAITABLE_TIMER_SERVICE_HPP
169