Commit a5c8450e authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

supported new methods for the interval timer: getting interval and canceling

the timer.
parent d55bcb9c
......@@ -386,6 +386,10 @@ public:
void setupTimer(const IntervalTimer::Callback& cbfunc,
const uint32_t interval);
void callback(const asio::error_code& error);
void cancel() {
timer_.cancel();
interval_ = 0;
}
uint32_t getInterval() const { return (interval_); }
private:
// a function to update timer_ when it expires
......@@ -399,7 +403,7 @@ private:
};
IntervalTimerImpl::IntervalTimerImpl(IOService& io_service) :
timer_(io_service.get_io_service())
interval_(0), timer_(io_service.get_io_service())
{}
IntervalTimerImpl::~IntervalTimerImpl()
......@@ -428,6 +432,10 @@ IntervalTimerImpl::setupTimer(const IntervalTimer::Callback& cbfunc,
void
IntervalTimerImpl::updateTimer() {
if (interval_ == 0) {
// timer has been canceled. Do nothing.
return;
}
try {
// Update expire time to (current time + interval_).
timer_.expires_from_now(boost::posix_time::seconds(interval_));
......@@ -462,6 +470,11 @@ IntervalTimer::setupTimer(const Callback& cbfunc, const uint32_t interval) {
return (impl_->setupTimer(cbfunc, interval));
}
void
IntervalTimer::cancel() {
impl_->cancel();
}
uint32_t
IntervalTimer::getInterval() const {
return (impl_->getInterval());
......
......@@ -658,7 +658,26 @@ public:
///
void setupTimer(const Callback& cbfunc, const uint32_t interval);
/// TBD
/// Cancel the timer.
///
/// If the timer has been set up, this method cancels any asynchronous
/// events waiting on the timer and stops the timer itself.
/// If the timer has already been canceled, this method effectively does
/// nothing.
///
/// This method never throws an exception.
void cancel();
/// Return the timer interval.
///
/// This method returns the timer interval in seconds if it's running;
/// if the timer has been canceled it returns 0.
///
/// This method never throws an exception.
///
/// Note: We may want to change the granularity of the timer to
/// milliseconds or even finer. If and when this happens the semantics
/// of the return value of this method will be changed accordingly.
uint32_t getInterval() const;
private:
......
......@@ -751,7 +751,7 @@ TEST_F(ASIOLinkTest, recursiveTimeout) {
// or not.
class IntervalTimerTest : public ::testing::Test {
protected:
IntervalTimerTest() : io_service_() {};
IntervalTimerTest() : io_service_() {}
~IntervalTimerTest() {}
class TimerCallBack : public std::unary_function<void, void> {
public:
......@@ -811,6 +811,19 @@ protected:
int count_;
int prev_counter_;
};
class TimerCallBackCanceller {
public:
TimerCallBackCanceller(unsigned int& counter, IntervalTimer& itimer) :
counter_(counter), itimer_(itimer)
{}
void operator()() {
++counter_;
itimer_.cancel();
}
private:
unsigned int& counter_;
IntervalTimer& itimer_;
};
class TimerCallBackOverwriter : public std::unary_function<void, void> {
public:
TimerCallBackOverwriter(IntervalTimerTest* test_obj,
......@@ -927,6 +940,23 @@ TEST_F(IntervalTimerTest, destructIntervalTimer) {
EXPECT_TRUE(timer_cancel_success_);
}
TEST_F(IntervalTimerTest, cancel) {
// Similar to destructIntervalTimer test, but the first timer explicitly
// cancels itself on first callback.
IntervalTimer itimer_counter(io_service_);
IntervalTimer itimer_watcher(io_service_);
unsigned int counter = 0;
itimer_counter.setupTimer(TimerCallBackCanceller(counter, itimer_counter),
1);
itimer_watcher.setupTimer(TimerCallBack(this), 3);
io_service_.run();
EXPECT_EQ(1, counter);
EXPECT_EQ(0, itimer_counter.getInterval());
// canceling an already canceled timer shouldn't cause any surprise.
EXPECT_NO_THROW(itimer_counter.cancel());
}
TEST_F(IntervalTimerTest, overwriteIntervalTimer) {
// Note: This test currently takes 4 seconds. The timer should have
// finer granularity and timer periods in this test should be shorter
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment