Timer, TimerUser rewritten.

master
Denes Matetelki 13 years ago
parent 6795075697
commit 1dfcecc661

@ -1,21 +1,9 @@
#ifndef TIMER_HPP #ifndef TIMER_HPP
#define TIMER_HPP #define TIMER_HPP
#include "TimerUser.hpp"
#include <time.h> // timer_t #include <time.h> // timer_t
#include <map>
class TimerUser
{
public:
virtual void timerExpired() = 0;
virtual void timerDestroyed() = 0;
virtual ~TimerUser() {}
}; // class TimerUser
class Timer class Timer
@ -23,27 +11,16 @@ class Timer
public: public:
Timer(); static timer_t createTimer( TimerUser *timerUser,
const clockid_t clockId = CLOCK_MONOTONIC );
virtual ~Timer();
timer_t createTimer( TimerUser *m_timerUser,
clockid_t clockId = CLOCK_MONOTONIC );
bool setTimer( timer_t timerId,
const time_t interval_sec,
const long interval_nsec = 0,
const time_t initExpr_sec = 0,
const long initExpr_nsec = 0 );
bool stopTimer( timer_t timerId );
private:
typedef std::map<timer_t, TimerUser*> TimerUserMap; static bool setTimer( timer_t &timerId,
const time_t interval_sec,
const long interval_nsec = 0,
const time_t initExpr_sec = 0,
const long initExpr_nsec = 0 );
TimerUserMap m_timerUsers; static bool deleteTimer(timer_t &timerId);
}; // class Timer }; // class Timer

@ -0,0 +1,37 @@
#ifndef TIMER_USER_HPP
#define TIMER_USER_HPP
#include <time.h> // timer_t
class TimerUser
{
public:
virtual void timerExpired() = 0;
protected:
TimerUser(const clockid_t clockId = CLOCK_MONOTONIC);
virtual ~TimerUser();
bool startTimer(const time_t interval_sec,
const long interval_nsec = 0,
const time_t initExpr_sec = 0,
const long initExpr_nsec = 0);
bool stopTimer();
private:
TimerUser(const TimerUser&);
TimerUser& operator=(const TimerUser&);
timer_t m_timerId;
}; // class TimerUser
#endif // TIMMER_USER_HPP

@ -3,9 +3,10 @@
#include "Logger.hpp" #include "Logger.hpp"
#include "Common.hpp" #include "Common.hpp"
#include <signal.h> // sigset_t
#include <time.h>
#include <errno.h> #include <errno.h>
#include <signal.h> // sigevent
void notifyFunction(union sigval sigVal) void notifyFunction(union sigval sigVal)
{ {
@ -15,27 +16,10 @@ void notifyFunction(union sigval sigVal)
} }
Timer::Timer()
: m_timerUsers()
{
TRACE;
}
Timer::~Timer()
{
TRACE;
for (TimerUserMap::iterator it = m_timerUsers.begin(); it != m_timerUsers.end(); )
stopTimer((it++)->first);
m_timerUsers.clear();
}
timer_t Timer::createTimer( TimerUser *timerUser, timer_t Timer::createTimer( TimerUser *timerUser,
clockid_t clockId ) const clockid_t clockId )
{ {
TRACE; TRACE_STATIC;
sigevent sigev; sigevent sigev;
timer_t timerId(0); timer_t timerId(0);
@ -48,34 +32,24 @@ timer_t Timer::createTimer( TimerUser *timerUser,
if (timer_create(clockId, &sigev, &timerId) == -1) { if (timer_create(clockId, &sigev, &timerId) == -1) {
LOG_BEGIN(Logger::ERR) LOG_BEGIN(Logger::ERR)
LOG_PROP("Error message", strerror(errno)) LOG_PROP("Error message", strerror(errno))
LOG_END("Could create timer."); LOG_END_STATIC("Could create timer.");
return 0;
}
if (m_timerUsers.find(timerId) != m_timerUsers.end() ) {
LOG_BEGIN(Logger::ERR)
LOG_SPROP(timerId)
LOG_END("TimerId already in map.");
return 0; return 0;
} }
m_timerUsers.insert(std::make_pair(timerId, timerUser));
return timerId; return timerId;
} }
bool Timer::setTimer( timer_t timerId, bool Timer::setTimer( timer_t &timerId,
const time_t interval_sec, const time_t interval_sec,
const long interval_nsec, const long interval_nsec,
const time_t initExpr_sec, const time_t initExpr_sec,
const long initExpr_nsec ) const long initExpr_nsec )
{ {
if (m_timerUsers.find(timerId) == m_timerUsers.end() ) { TRACE_STATIC;
LOG_BEGIN(Logger::ERR)
LOG_SPROP(timerId) if (timerId == 0)
LOG_END("TimerId is not in the map.");
return false; return false;
}
itimerspec its; itimerspec its;
its.it_value.tv_sec = interval_sec; its.it_value.tv_sec = interval_sec;
@ -86,26 +60,28 @@ bool Timer::setTimer( timer_t timerId,
if (timer_settime( timerId, 0, &its, NULL ) == -1) { if (timer_settime( timerId, 0, &its, NULL ) == -1) {
LOG_BEGIN(Logger::ERR) LOG_BEGIN(Logger::ERR)
LOG_PROP("Error message", strerror(errno)) LOG_PROP("Error message", strerror(errno))
LOG_END("Could set timer."); LOG_END_STATIC("Could set timer.");
return false; return false;
} }
return true; return true;
} }
bool Timer::stopTimer( timer_t timerId ) bool Timer::deleteTimer(timer_t &timerId)
{ {
TRACE; TRACE_STATIC;
if (timerId == 0)
return false;
if (m_timerUsers.find(timerId) == m_timerUsers.end() ) { if (timer_delete(timerId) == -1) {
LOG_BEGIN(Logger::ERR) LOG_BEGIN(Logger::ERR)
LOG_SPROP(timerId) LOG_PROP("Error message", strerror(errno))
LOG_END("TimerId is not in the map."); LOG_END_STATIC("Could delete timer.");
return false; return false;
} }
setTimer(timerId, 0); timerId = 0;
m_timerUsers[timerId]->timerDestroyed(); return false;
m_timerUsers.erase(timerId);
return true;
} }

@ -0,0 +1,42 @@
#include "TimerUser.hpp"
#include "Logger.hpp"
#include "Common.hpp"
#include "Timer.hpp"
#include <errno.h>
TimerUser::TimerUser(const clockid_t clockId)
: m_timerId(Timer::createTimer(this, clockId))
{
TRACE;
}
TimerUser::~TimerUser()
{
TRACE;
Timer::deleteTimer(m_timerId);
}
bool TimerUser::startTimer(const time_t interval_sec,
const long interval_nsec,
const time_t initExpr_sec,
const long initExpr_nsec)
{
TRACE;
return Timer::setTimer(m_timerId, interval_sec, interval_nsec, initExpr_sec, initExpr_nsec);
}
bool TimerUser::stopTimer()
{
TRACE;
return Timer::setTimer(m_timerId, 0);
}

@ -2,197 +2,48 @@
#include "Fixture.hpp" #include "Fixture.hpp"
#include "Timer.hpp" #include "Timer.hpp"
#include "Thread.hpp"
#include <signal.h>
#include <climits>
class TestTimer : public CxxTest::TestSuite class TestTimer : public CxxTest::TestSuite
{ {
public:
private: void testCreateTimerInvalidClockId()
class DummyTimerUser : public TimerUser
{
public:
DummyTimerUser()
: m_counter(0)
{
TRACE;
}
~DummyTimerUser()
{
TRACE;
}
void timerExpired()
{
TRACE;
m_counter++;
}
void timerDestroyed()
{
TRACE;
m_counter += 100;
}
int m_counter;
}; // class TimerUser
public:
void testBasicTimer( void )
{
TEST_HEADER;
DummyTimerUser timerUser;
Timer timer;
timer_t timerId = timer.createTimer( &timerUser );
timer.setTimer(timerId, 2);
sleep( 4 );
// one expiration, no destroy
TS_ASSERT_EQUALS( timerUser.m_counter, 1 );
}
void testStopTimer( void )
{
TEST_HEADER;
DummyTimerUser timerUser;
Timer timer;
timer_t timerId = timer.createTimer( &timerUser );
timer.setTimer(timerId, 10);
sleep( 2 );
timer.stopTimer( timerId );
// no expiration, just destroy
TS_ASSERT_EQUALS( timerUser.m_counter, 100 );
}
void testPeriodicTimer( void )
{
TEST_HEADER;
DummyTimerUser timerUser;
Timer timer;
timer_t timerId = timer.createTimer( &timerUser );
// after 1 sec, expire periodically at each sec
timer.setTimer(timerId, 1, 0, 1, 0);
sleep(4);
timer.stopTimer( timerId );
// 1 destroy(stop) + 3 expiration (+- 1)
TS_ASSERT_DELTA( timerUser.m_counter, 103, 1 );
}
void testOneUserManyTimers( void )
{ {
TEST_HEADER; TEST_HEADER;
DummyTimerUser timerUser; TimerUser *timerUser(0);
Timer timer; clockid_t clockId(10); // clockid_t is valid [0,6]
timer_t timerId = timer.createTimer( &timerUser );
timer.setTimer(timerId, 1);
timer_t timerId2 = timer.createTimer( &timerUser );
timer.setTimer(timerId2, 2);
timer_t timerId3 = timer.createTimer( &timerUser ); TS_ASSERT_EQUALS(Timer::createTimer(timerUser, clockId), (void*)0);
timer.setTimer(timerId3, 3);
sleep(4);
timer.stopTimer( timerId );
TS_ASSERT_EQUALS( timerUser.m_counter, 100 + 1 + 1 + 1 );
} }
void testMenyUserManyTimers( void ) void testSetTimerInvalidTimerId()
{ {
TEST_HEADER; TEST_HEADER;
DummyTimerUser timerUser; timer_t timerId((void*)0);
DummyTimerUser timerUser2; TS_ASSERT_EQUALS(Timer::setTimer(timerId, 1), false);
DummyTimerUser timerUser3;
Timer timer;
timer_t timerId = timer.createTimer( &timerUser );
timer.setTimer(timerId, 1);
timer_t timerId2 = timer.createTimer( &timerUser );
timer.setTimer(timerId2, 2);
timer_t timerId3 = timer.createTimer( &timerUser );
timer.setTimer(timerId3, 3);
timer_t timerId4 = timer.createTimer( &timerUser2 );
timer.setTimer(timerId4, 1);
timer_t timerId5 = timer.createTimer( &timerUser2 );
timer.setTimer(timerId5, 2);
sleep(4);
TS_ASSERT_EQUALS( timerUser.m_counter, 1 + 1 + 1 );
TS_ASSERT_EQUALS( timerUser2.m_counter, 1 + 1 );
TS_ASSERT_EQUALS( timerUser3.m_counter, 0 );
} }
void test2Timer( void ) void testSetTimerInvalidTime()
{ {
TEST_HEADER; TEST_HEADER;
DummyTimerUser timerUser; timer_t timerId = Timer::createTimer(0, 1);
TS_ASSERT_EQUALS(Timer::setTimer(timerId, -1), false);
Timer timer; Timer::deleteTimer(timerId);
Timer timer2;
timer_t timerId = timer.createTimer( &timerUser );
timer.setTimer(timerId, 1);
timer_t timerId2 = timer.createTimer( &timerUser );
timer.setTimer(timerId2, 2);
timer_t timerId3 = timer.createTimer( &timerUser );
timer.setTimer(timerId3, 3);
timer_t timerId4 = timer.createTimer( &timerUser );
timer2.setTimer(timerId4, 1);
timer_t timerId5 = timer.createTimer( &timerUser );
timer2.setTimer(timerId5, 2);
sleep(4);
TS_ASSERT_EQUALS( timerUser.m_counter, (1 + 1 + 1) + (1 + 1) );
} }
void testStopTimerWhichIsNotInTheMap() void testDeleteTimerInvalidTimerId()
{ {
TEST_HEADER; TEST_HEADER;
Timer timer; timer_t timerId((void*)0);
TS_ASSERT_EQUALS(Timer::deleteTimer(timerId), false);
timer_t timerId = (void*)1234;
TS_ASSERT_EQUALS(timer.stopTimer( timerId ), false);
} }
void testSetTimerWhichIsNotInTheMap() };
{
TEST_HEADER;
Timer timer;
timer_t timerId = (void*)1234;
TS_ASSERT_EQUALS(timer.setTimer( timerId, 1 ), false);
}
};

@ -0,0 +1,115 @@
#include <cxxtest/TestSuite.h>
#include "Fixture.hpp"
#define protected public
#include "Timer.hpp"
class TestTimerUser : public CxxTest::TestSuite
{
private:
class DummyTimerUser : public TimerUser
{
public:
DummyTimerUser()
: m_counter(0)
{
TRACE;
}
~DummyTimerUser()
{
TRACE;
}
void timerExpired()
{
TRACE;
m_counter++;
}
int m_counter;
}; // class TimerUser
public:
void testBasicTimer( void )
{
TEST_HEADER;
DummyTimerUser timerUser;
timerUser.startTimer(1);
sleep(2);
// one expiration
TS_ASSERT_EQUALS( timerUser.m_counter, 1 );
}
void testStopTimer( void )
{
TEST_HEADER;
DummyTimerUser timerUser;
timerUser.startTimer(10);
sleep(1);
timerUser.stopTimer();
// no expiration
TS_ASSERT_EQUALS( timerUser.m_counter, 0 );
}
void testPeriodicTimer( void )
{
TEST_HEADER;
DummyTimerUser timerUser;
// after 1 sec, expire periodically at each sec
timerUser.startTimer(1, 0, 1, 0);
sleep(4);
timerUser.stopTimer();
// 3 expiration (+- 1)
TS_ASSERT_DELTA( timerUser.m_counter, 3, 1 );
}
void test2TimerUsers( void )
{
TEST_HEADER;
DummyTimerUser t1;
DummyTimerUser t2;
t1.startTimer(0, 5000);
t2.startTimer(0, 6000);
sleep(1);
TS_ASSERT_EQUALS( t1.m_counter, 1 );
TS_ASSERT_EQUALS( t2.m_counter, 1 );
}
void testStopNotStartedTimer( void )
{
TEST_HEADER;
DummyTimerUser timerUser;
timerUser.stopTimer();
// timerDestroyed not called
TS_ASSERT_EQUALS( timerUser.m_counter, 0 );
}
};
Loading…
Cancel
Save