From 8622f69e271220bed002619020864816d79f3cd5 Mon Sep 17 00:00:00 2001 From: Andrew Geissler Date: Sun, 2 Apr 2017 18:19:00 -0500 Subject: Support custom callback function on timer expiration Change-Id: I39b32d608ef342d63c57cbc1902e927fb39861c7 Signed-off-by: Andrew Geissler --- softoff/test/utest.cpp | 103 ++++++++++++++++++++++++++++++++++++++++++++++++- softoff/timer.cpp | 6 +++ softoff/timer.hpp | 11 +++++- 3 files changed, 117 insertions(+), 3 deletions(-) (limited to 'softoff') diff --git a/softoff/test/utest.cpp b/softoff/test/utest.cpp index a9dae9c..9ffb04e 100644 --- a/softoff/test/utest.cpp +++ b/softoff/test/utest.cpp @@ -15,7 +15,7 @@ class TimerTest : public ::testing::Test int rc; // Source of event - sd_event_source* eventSource; + sd_event_source* eventSource = nullptr; // Add a Timer Object Timer timer; @@ -37,6 +37,51 @@ class TimerTest : public ::testing::Test } }; + +class TimerTestCallBack : public ::testing::Test +{ + public: + // systemd event handler + sd_event* events; + + // Need this so that events can be initialized. + int rc; + + // Source of event + sd_event_source* eventSource = nullptr; + + // Add a Timer Object + std::unique_ptr timer = nullptr; + + // Indicates optional call back fun was called + bool callBackDone = false; + + void callBack() + { + callBackDone = true; + } + + // Gets called as part of each TEST_F construction + TimerTestCallBack() + : rc(sd_event_default(&events)) + + { + // Check for successful creation of + // event handler and timer object. + EXPECT_GE(rc, 0); + + std::function func(std::bind( + &TimerTestCallBack::callBack, this)); + timer = std::make_unique(events, func); + } + + // Gets called as part of each TEST_F destruction + ~TimerTestCallBack() + { + events = sd_event_unref(events); + } +}; + /** @brief Makes sure that timer is expired and the * callback handler gets invoked post 2 seconds */ @@ -162,3 +207,59 @@ TEST_F(TimerTest, updateTimerAndNeverExpire) // 2 becase of one more count that happens prior to exiting EXPECT_EQ(2, count); } + +/** @brief Makes sure that optional callback is called */ +TEST_F(TimerTestCallBack, optionalFuncCallBackDone) +{ + using namespace std::chrono; + + auto time = duration_cast(seconds(2)); + EXPECT_GE(timer->startTimer(time), 0); + + // Waiting 2 seconds is enough here since we have + // already spent some usec now + int count = 0; + while(count < 2 && !timer->isExpired()) + { + // Returns -0- on timeout and positive number on dispatch + auto sleepTime = duration_cast(seconds(1)); + if(!sd_event_run(events, sleepTime.count())) + { + count++; + } + } + EXPECT_EQ(true, timer->isExpired()); + EXPECT_EQ(true, callBackDone); + EXPECT_EQ(1, count); +} + +/** @brief Makes sure that timer is not expired + */ +TEST_F(TimerTestCallBack, timerNotExpiredAfter2SecondsNoOptionalCallBack) +{ + using namespace std::chrono; + + auto time = duration_cast(seconds(2)); + EXPECT_GE(timer->startTimer(time), 0); + + // Now turn off the timer post a 1 second sleep + sleep(1); + EXPECT_GE(timer->setTimer(SD_EVENT_OFF), 0); + + // Wait 2 seconds and see that timer is not expired + int count = 0; + while(count < 2) + { + // Returns -0- on timeout + auto sleepTime = duration_cast(seconds(1)); + if(!sd_event_run(events, sleepTime.count())) + { + count++; + } + } + EXPECT_EQ(false, timer->isExpired()); + EXPECT_EQ(false, callBackDone); + + // 2 because of one more count that happens prior to exiting + EXPECT_EQ(2, count); +} diff --git a/softoff/timer.cpp b/softoff/timer.cpp index c626536..4e8fd9a 100644 --- a/softoff/timer.cpp +++ b/softoff/timer.cpp @@ -51,6 +51,12 @@ int Timer::timeoutHandler(sd_event_source* eventSource, auto timer = static_cast(userData); timer->expired = true; + // Call optional user call back function if available + if(timer->userCallBack) + { + timer->userCallBack(); + } + log("Timer expired"); return 0; } diff --git a/softoff/timer.hpp b/softoff/timer.hpp index 9d597f8..cbd3444 100644 --- a/softoff/timer.hpp +++ b/softoff/timer.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include namespace phosphor { @@ -22,9 +23,12 @@ class Timer /** @brief Constructs timer object * * @param[in] events - sd_event pointer + * @param[in] funcCallBack - optional function callback for timer + * expirations */ - Timer(sd_event* events) - : timeEvent(events) + Timer(sd_event* events, + std::function userCallBack = nullptr) + : timeEvent(events), userCallBack(userCallBack) { // Initialize the timer initialize(); @@ -87,6 +91,9 @@ class Timer /** @brief Gets the current time from steady clock */ static std::chrono::microseconds getTime(); + + /** @brief Optional function to call on timer expiration */ + std::function userCallBack; }; } // namespace ipmi -- cgit v1.2.1