Kea  1.5.0
interval_timer.cc
Go to the documentation of this file.
1 // Copyright (C) 2011-2017 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/bind.hpp>
13 #include <boost/enable_shared_from_this.hpp>
14 #include <boost/shared_ptr.hpp>
15 
16 #include <exceptions/exceptions.h>
17 
18 namespace isc {
19 namespace asiolink {
20 
29  public boost::enable_shared_from_this<IntervalTimerImpl>
30 {
31 private:
32  // prohibit copy
33  IntervalTimerImpl(const IntervalTimerImpl& source);
34  IntervalTimerImpl& operator=(const IntervalTimerImpl& source);
35 public:
36  IntervalTimerImpl(IOService& io_service);
38  void setup(const IntervalTimer::Callback& cbfunc, const long interval,
39  const IntervalTimer::Mode& interval_mode
41  void callback(const boost::system::error_code& error);
42  void cancel() {
43  timer_.cancel();
44  interval_ = 0;
45  }
46  long getInterval() const { return (interval_); }
47 private:
48  // a function to update timer_ when it expires
49  void update();
50  // a function to call back when timer_ expires
52  // interval in milliseconds
53  long interval_;
54  // asio timer
55  boost::asio::deadline_timer timer_;
56 
57  // Controls how the timer behaves after expiration.
58  IntervalTimer::Mode mode_;
59 
60  // interval_ will be set to this value in destructor in order to detect
61  // use-after-free type of bugs.
62  static const long INVALIDATED_INTERVAL = -1;
63 };
64 
65 IntervalTimerImpl::IntervalTimerImpl(IOService& io_service) :
66  interval_(0), timer_(io_service.get_io_service()),
67  mode_(IntervalTimer::REPEATING)
68 {}
69 
71  interval_ = INVALIDATED_INTERVAL;
72 }
73 
74 void
76  const long interval,
77  const IntervalTimer::Mode& mode)
78 {
79  // Interval should not be less than 0.
80  if (interval < 0) {
81  isc_throw(isc::BadValue, "Interval should not be less than or "
82  "equal to 0");
83  }
84  // Call back function should not be empty.
85  if (cbfunc.empty()) {
86  isc_throw(isc::InvalidParameter, "Callback function is empty");
87  }
88  cbfunc_ = cbfunc;
89  interval_ = interval;
90  mode_ = mode;
91 
92  // Set initial expire time.
93  // At this point the timer is not running yet and will not expire.
94  // After calling IOService::run(), the timer will expire.
95  update();
96 }
97 
98 void
99 IntervalTimerImpl::update() {
100  try {
101  // Update expire time to (current time + interval_).
102  timer_.expires_from_now(boost::posix_time::millisec(interval_));
103  // Reset timer.
104  // Pass a function bound with a shared_ptr to this.
105  timer_.async_wait(boost::bind(&IntervalTimerImpl::callback,
106  shared_from_this(),
107  boost::asio::placeholders::error));
108  } catch (const boost::system::system_error& e) {
109  isc_throw(isc::Unexpected, "Failed to update timer: " << e.what());
110  } catch (const boost::bad_weak_ptr&) {
111  // Can't happen. It means a severe internal bug.
112  assert(0);
113  }
114 }
115 
116 void
117 IntervalTimerImpl::callback(const boost::system::error_code& ec) {
118  assert(interval_ != INVALIDATED_INTERVAL);
119  if (interval_ == 0 || ec) {
120  // timer has been canceled. Do nothing.
121  } else {
122  // If we should repeat, set next expire time.
123  if (mode_ == IntervalTimer::REPEATING) {
124  update();
125  }
126 
127  // Invoke the call back function.
128  cbfunc_();
129  }
130 }
131 
132 IntervalTimer::IntervalTimer(IOService& io_service) :
133  impl_(new IntervalTimerImpl(io_service))
134 {}
135 
137  // Cancel the timer to make sure cbfunc_() will not be called any more.
138  cancel();
139 }
140 
141 void
142 IntervalTimer::setup(const Callback& cbfunc, const long interval,
143  const IntervalTimer::Mode& mode) {
144  return (impl_->setup(cbfunc, interval, mode));
145 }
146 
147 void
149  impl_->cancel();
150 }
151 
152 long
154  return (impl_->getInterval());
155 }
156 
157 } // namespace asiolink
158 } // namespace isc
isc::Unexpected
A generic exception that is thrown when an unexpected error condition occurs.
Definition: exceptions/exceptions.h:153
mode_
CompressMode mode_
Definition: rdatafields.cc:97
io_service.h
isc
Defines the logger used by the top-level component of kea-dhcp-ddns.
Definition: agent_parser.cc:144
isc::Exception::what
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
Definition: exceptions/exceptions.cc:32
isc_throw
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Definition: exceptions/exceptions.h:192
isc::InvalidParameter
A generic exception that is thrown if a parameter given to a method or function is considered invalid...
Definition: exceptions/exceptions.h:124
isc::BadValue
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
Definition: exceptions/exceptions.h:132
exceptions.h
interval_timer.h
asio_wrapper.h