Kea 3.0.2-git
interval_timer.cc
Go to the documentation of this file.
1// Copyright (C) 2011-2024 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#include <config.h>
10#include <asiolink/io_service.h>
11
12#include <boost/enable_shared_from_this.hpp>
13#include <boost/noncopyable.hpp>
14#include <boost/shared_ptr.hpp>
15#include <boost/asio/deadline_timer.hpp>
16
18
19#include <atomic>
20#include <functional>
21#include <mutex>
22
23using namespace std;
24namespace ph = std::placeholders;
25
26namespace isc {
27namespace asiolink {
28
37 public boost::enable_shared_from_this<IntervalTimerImpl>,
38 public boost::noncopyable {
39public:
40
44 IntervalTimerImpl(const IOServicePtr& io_service);
45
48
54 void setup(const IntervalTimer::Callback& cbfunc, const long interval,
55 const IntervalTimer::Mode& interval_mode = IntervalTimer::REPEATING);
56
60 void callback(const boost::system::error_code& error);
61
63 void cancel() {
64 lock_guard<mutex> lk (mutex_);
65 timer_.cancel();
66 interval_ = 0;
67 cbfunc_ = std::function<void()>();
68 }
69
73 long getInterval() const { return (interval_); }
74
75private:
76
80 void update();
81
84
86 std::atomic<long> interval_;
87
89 IOServicePtr io_service_;
90
92 boost::asio::deadline_timer timer_;
93
96
98 std::mutex mutex_;
99
104 static const long INVALIDATED_INTERVAL = -1;
105};
106
108 interval_(0), io_service_(io_service), timer_(io_service_->getInternalIOService()),
109 mode_(IntervalTimer::REPEATING) {
110}
111
113 interval_ = INVALIDATED_INTERVAL;
114}
115
116void
118 const long interval,
119 const IntervalTimer::Mode& mode) {
120 // Interval should not be less than 0.
121 if (interval < 0) {
122 isc_throw(isc::BadValue, "Interval should not be less than or "
123 "equal to 0");
124 }
125 // Call back function should not be empty.
126 if (!cbfunc) {
127 isc_throw(isc::InvalidParameter, "Callback function is empty");
128 }
129
130 lock_guard<mutex> lk(mutex_);
131 cbfunc_ = cbfunc;
132 interval_ = interval;
133 mode_ = mode;
134
135 // Set initial expire time.
136 // At this point the timer is not running yet and will not expire.
137 // After calling IOService::run(), the timer will expire.
138 update();
139}
140
141void
142IntervalTimerImpl::update() {
143 try {
144 // Update expire time to (current time + interval_).
145 timer_.expires_from_now(boost::posix_time::millisec(long(interval_)));
146 // Reset timer.
147 // Pass a function bound with a shared_ptr to this.
148 timer_.async_wait(std::bind(&IntervalTimerImpl::callback,
149 shared_from_this(),
150 ph::_1)); //error
151 } catch (const boost::system::system_error& e) {
152 isc_throw(isc::Unexpected, "Failed to update timer: " << e.what());
153 } catch (const boost::bad_weak_ptr&) {
154 // Can't happen. It means a severe internal bug.
155 }
156}
157
158void
159IntervalTimerImpl::callback(const boost::system::error_code& ec) {
160 if (interval_ == INVALIDATED_INTERVAL) {
161 isc_throw(isc::BadValue, "Interval internal state");
162 }
163 if (interval_ == 0 || ec) {
164 // timer has been canceled. Do nothing.
165 } else {
166 {
167 lock_guard<mutex> lk(mutex_);
168 // If we should repeat, set next expire time.
169 if (mode_ == IntervalTimer::REPEATING) {
170 update();
171 }
172 }
173
174 // Invoke the call back function.
175 cbfunc_();
176 }
177}
178
179IntervalTimer::IntervalTimer(const IOServicePtr& io_service) :
180 impl_(new IntervalTimerImpl(io_service)) {
181}
182
184 // Cancel the timer to make sure cbfunc_() will not be called any more.
185 cancel();
186}
187
188void
189IntervalTimer::setup(const Callback& cbfunc, const long interval,
190 const IntervalTimer::Mode& mode) {
191 return (impl_->setup(cbfunc, interval, mode));
192}
193
194void
196 impl_->cancel();
197}
198
199long
201 return (impl_->getInterval());
202}
203
204} // namespace asiolink
205} // namespace isc
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
A generic exception that is thrown if a parameter given to a method or function is considered invalid...
A generic exception that is thrown when an unexpected error condition occurs.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Defines the logger used by the top-level component of kea-lfc.