Kea 2.6.0
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
17
18#include <atomic>
19#include <functional>
20#include <mutex>
21
22using namespace std;
23namespace ph = std::placeholders;
24
25namespace isc {
26namespace asiolink {
27
36 public boost::enable_shared_from_this<IntervalTimerImpl>,
37 public boost::noncopyable {
38public:
39
43 IntervalTimerImpl(const IOServicePtr& io_service);
44
47
53 void setup(const IntervalTimer::Callback& cbfunc, const long interval,
54 const IntervalTimer::Mode& interval_mode = IntervalTimer::REPEATING);
55
59 void callback(const boost::system::error_code& error);
60
62 void cancel() {
63 lock_guard<mutex> lk (mutex_);
64 timer_.cancel();
65 interval_ = 0;
66 cbfunc_ = std::function<void()>();
67 }
68
72 long getInterval() const { return (interval_); }
73
74private:
75
79 void update();
80
83
85 std::atomic<long> interval_;
86
88 IOServicePtr io_service_;
89
91 boost::asio::deadline_timer timer_;
92
95
97 std::mutex mutex_;
98
103 static const long INVALIDATED_INTERVAL = -1;
104};
105
107 interval_(0), io_service_(io_service), timer_(io_service_->getInternalIOService()),
108 mode_(IntervalTimer::REPEATING) {
109}
110
112 interval_ = INVALIDATED_INTERVAL;
113}
114
115void
117 const long interval,
118 const IntervalTimer::Mode& mode) {
119 // Interval should not be less than 0.
120 if (interval < 0) {
121 isc_throw(isc::BadValue, "Interval should not be less than or "
122 "equal to 0");
123 }
124 // Call back function should not be empty.
125 if (!cbfunc) {
126 isc_throw(isc::InvalidParameter, "Callback function is empty");
127 }
128
129 lock_guard<mutex> lk(mutex_);
130 cbfunc_ = cbfunc;
131 interval_ = interval;
132 mode_ = mode;
133
134 // Set initial expire time.
135 // At this point the timer is not running yet and will not expire.
136 // After calling IOService::run(), the timer will expire.
137 update();
138}
139
140void
141IntervalTimerImpl::update() {
142 try {
143 // Update expire time to (current time + interval_).
144 timer_.expires_from_now(boost::posix_time::millisec(long(interval_)));
145 // Reset timer.
146 // Pass a function bound with a shared_ptr to this.
147 timer_.async_wait(std::bind(&IntervalTimerImpl::callback,
148 shared_from_this(),
149 ph::_1)); //error
150 } catch (const boost::system::system_error& e) {
151 isc_throw(isc::Unexpected, "Failed to update timer: " << e.what());
152 } catch (const boost::bad_weak_ptr&) {
153 // Can't happen. It means a severe internal bug.
154 }
155}
156
157void
158IntervalTimerImpl::callback(const boost::system::error_code& ec) {
159 if (interval_ == INVALIDATED_INTERVAL) {
160 isc_throw(isc::BadValue, "Interval internal state");
161 }
162 if (interval_ == 0 || ec) {
163 // timer has been canceled. Do nothing.
164 } else {
165 {
166 lock_guard<mutex> lk(mutex_);
167 // If we should repeat, set next expire time.
168 if (mode_ == IntervalTimer::REPEATING) {
169 update();
170 }
171 }
172
173 // Invoke the call back function.
174 cbfunc_();
175 }
176}
177
178IntervalTimer::IntervalTimer(const IOServicePtr& io_service) :
179 impl_(new IntervalTimerImpl(io_service)) {
180}
181
183 // Cancel the timer to make sure cbfunc_() will not be called any more.
184 cancel();
185}
186
187void
188IntervalTimer::setup(const Callback& cbfunc, const long interval,
189 const IntervalTimer::Mode& mode) {
190 return (impl_->setup(cbfunc, interval, mode));
191}
192
193void
195 impl_->cancel();
196}
197
198long
200 return (impl_->getInterval());
201}
202
203} // namespace asiolink
204} // 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.