2
// deadline_timer_service.hpp
3
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
5
// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
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)
11
#ifndef ASIO_DETAIL_DEADLINE_TIMER_SERVICE_HPP
12
#define ASIO_DETAIL_DEADLINE_TIMER_SERVICE_HPP
14
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
16
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18
#include "asio/detail/push_options.hpp"
20
#include "asio/detail/push_options.hpp"
22
#include <boost/config.hpp>
23
#include <boost/date_time/posix_time/posix_time_types.hpp>
24
#include "asio/detail/pop_options.hpp"
26
#include "asio/error.hpp"
27
#include "asio/io_service.hpp"
28
#include "asio/detail/bind_handler.hpp"
29
#include "asio/detail/handler_base_from_member.hpp"
30
#include "asio/detail/noncopyable.hpp"
31
#include "asio/detail/service_base.hpp"
32
#include "asio/detail/socket_ops.hpp"
33
#include "asio/detail/socket_types.hpp"
34
#include "asio/detail/timer_queue.hpp"
39
template <typename Time_Traits, typename Timer_Scheduler>
40
class deadline_timer_service
41
: public asio::detail::service_base<
42
deadline_timer_service<Time_Traits, Timer_Scheduler> >
46
typedef typename Time_Traits::time_type time_type;
49
typedef typename Time_Traits::duration_type duration_type;
51
// The implementation type of the timer. This type is dependent on the
52
// underlying implementation of the timer service.
53
struct implementation_type
54
: private asio::detail::noncopyable
57
bool might_have_pending_waits;
61
deadline_timer_service(asio::io_service& io_service)
62
: asio::detail::service_base<
63
deadline_timer_service<Time_Traits, Timer_Scheduler> >(io_service),
64
scheduler_(asio::use_service<Timer_Scheduler>(io_service))
66
scheduler_.init_task();
67
scheduler_.add_timer_queue(timer_queue_);
71
~deadline_timer_service()
73
scheduler_.remove_timer_queue(timer_queue_);
76
// Destroy all user-defined handler objects owned by the service.
77
void shutdown_service()
81
// Construct a new timer implementation.
82
void construct(implementation_type& impl)
84
impl.expiry = time_type();
85
impl.might_have_pending_waits = false;
88
// Destroy a timer implementation.
89
void destroy(implementation_type& impl)
95
// Cancel any asynchronous wait operations associated with the timer.
96
std::size_t cancel(implementation_type& impl, asio::error_code& ec)
98
if (!impl.might_have_pending_waits)
100
ec = asio::error_code();
103
std::size_t count = scheduler_.cancel_timer(timer_queue_, &impl);
104
impl.might_have_pending_waits = false;
105
ec = asio::error_code();
109
// Get the expiry time for the timer as an absolute time.
110
time_type expires_at(const implementation_type& impl) const
115
// Set the expiry time for the timer as an absolute time.
116
std::size_t expires_at(implementation_type& impl,
117
const time_type& expiry_time, asio::error_code& ec)
119
std::size_t count = cancel(impl, ec);
120
impl.expiry = expiry_time;
121
ec = asio::error_code();
125
// Get the expiry time for the timer relative to now.
126
duration_type expires_from_now(const implementation_type& impl) const
128
return Time_Traits::subtract(expires_at(impl), Time_Traits::now());
131
// Set the expiry time for the timer relative to now.
132
std::size_t expires_from_now(implementation_type& impl,
133
const duration_type& expiry_time, asio::error_code& ec)
135
return expires_at(impl,
136
Time_Traits::add(Time_Traits::now(), expiry_time), ec);
139
// Perform a blocking wait on the timer.
140
void wait(implementation_type& impl, asio::error_code& ec)
142
time_type now = Time_Traits::now();
143
while (Time_Traits::less_than(now, impl.expiry))
145
boost::posix_time::time_duration timeout =
146
Time_Traits::to_posix_duration(Time_Traits::subtract(impl.expiry, now));
148
tv.tv_sec = timeout.total_seconds();
149
tv.tv_usec = timeout.total_microseconds() % 1000000;
151
socket_ops::select(0, 0, 0, 0, &tv, ec);
152
now = Time_Traits::now();
154
ec = asio::error_code();
157
template <typename Handler>
159
public handler_base_from_member<Handler>
162
wait_handler(asio::io_service& io_service, Handler handler)
163
: handler_base_from_member<Handler>(handler),
164
io_service_(io_service),
169
void operator()(const asio::error_code& result)
171
io_service_.post(detail::bind_handler(this->handler_, result));
175
asio::io_service& io_service_;
176
asio::io_service::work work_;
179
// Start an asynchronous wait on the timer.
180
template <typename Handler>
181
void async_wait(implementation_type& impl, Handler handler)
183
impl.might_have_pending_waits = true;
184
scheduler_.schedule_timer(timer_queue_, impl.expiry,
185
wait_handler<Handler>(this->get_io_service(), handler), &impl);
189
// The queue of timers.
190
timer_queue<Time_Traits> timer_queue_;
192
// The object that schedules and executes timers. Usually a reactor.
193
Timer_Scheduler& scheduler_;
196
} // namespace detail
199
#include "asio/detail/pop_options.hpp"
201
#endif // ASIO_DETAIL_DEADLINE_TIMER_SERVICE_HPP