diff --git a/include/TimerThread.hpp b/include/TimerThread.hpp index 7410e29..ab3290c 100644 --- a/include/TimerThread.hpp +++ b/include/TimerThread.hpp @@ -7,7 +7,7 @@ #include "ConditionVariable.hpp" #include -#include // time_t +#include // timespec class TimerUser { @@ -29,7 +29,7 @@ class TimerThread : public Thread private: typedef struct { - time_t periodTime; + timespec periodTime; TimerUser* user; } UserEntry; @@ -40,9 +40,13 @@ public: virtual ~TimerThread(); - void addTimerUser(TimerUser* user, - const time_t expiration, - const time_t periodTime = 0 ); + void addTimerUser( TimerUser* user, + const time_t expiration, + const time_t periodTime = 0 ); + + void addTimerUser( TimerUser* user, + const timespec expiration, + const timespec periodTime = timespec_ctor() ); bool removeTimerUser ( void* timerUser ); @@ -54,10 +58,26 @@ private: void* run( void ); + // facory function + inline static timespec timespec_ctor() { + timespec tmp = { 0, 0 }; + return tmp; + }; + + // compare class for the multimap + class timespec_cmp { + public : + bool operator()(const timespec& a, const timespec& b) const { + if ( a.tv_sec < b.tv_sec ) return true; + if ( a.tv_sec > b.tv_sec ) return false; + return a.tv_nsec < b.tv_nsec; + } + }; + Mutex m_mutex; ConditionVariable m_condVar; - std::multimap m_users; + std::multimap< timespec, UserEntry, timespec_cmp> m_users; }; // class TimerThread diff --git a/src/TimerThread.cpp b/src/TimerThread.cpp index c1edc1c..b67822a 100644 --- a/src/TimerThread.cpp +++ b/src/TimerThread.cpp @@ -31,24 +31,39 @@ void TimerThread::addTimerUser(TimerUser* user, TRACE; ScopedLock sl( m_mutex ); if ( not m_isRunning ) return; - UserEntry userEntry = { periodTime, user }; - m_users.insert( std::pair( expiration, userEntry ) ); + timespec expirationTS = { expiration, 0 }; + timespec periodTimeTS = { periodTime, 0 }; + + UserEntry userEntry = { periodTimeTS, user }; + m_users.insert( std::pair( expirationTS, userEntry ) ); m_condVar.signal(); } +void TimerThread::addTimerUser( TimerUser* user, + const timespec expiration, + const timespec periodTime ) +{ + TRACE; + ScopedLock sl( m_mutex ); + if ( not m_isRunning ) return; + UserEntry userEntry = { periodTime, user }; + m_users.insert( std::pair( expiration, userEntry ) ); + m_condVar.signal(); +} + bool TimerThread::removeTimerUser ( void* timerUser ) { TRACE; ScopedLock sl( m_mutex ); if ( not m_isRunning ) return false; - std::multimap::iterator it, tmp; + std::multimap::iterator it, tmp; bool found(false); for ( it = m_users.begin(); it != m_users.end(); ) { tmp = it++; - /// @todo solveth e abstract pointer problem + /// @todo solve the abstract pointer problem if ( (void*)(it->second.user) == (void*)timerUser ) { m_users.erase(tmp); m_condVar.signal(); @@ -71,12 +86,12 @@ void TimerThread::stop() void* TimerThread::run( void ) { TRACE; - time_t nextExpiration; + timespec nextExpiration; - std::multimap tmp; - std::multimap::iterator it; - std::pair::iterator, - std::multimap::iterator> ret; + std::multimap tmp; + std::multimap::iterator it; + std::pair::iterator, + std::multimap::iterator> ret; while( m_isRunning ) { @@ -91,7 +106,8 @@ void* TimerThread::run( void ) m_mutex.lock(); // timer deleted / added, get nextExpiration again - if ( m_condVar.wait( nextExpiration ) != ETIMEDOUT ) { + if ( m_condVar.wait( nextExpiration.tv_sec, + nextExpiration.tv_nsec ) != ETIMEDOUT ) { continue; } m_mutex.unlock(); @@ -104,7 +120,8 @@ void* TimerThread::run( void ) tmp.clear(); for ( it = ret.first; it != ret.second; it++ ) { it->second.user->timerExpired(); - if ( it->second.periodTime ) tmp.insert(std::pair( + if ( it->second.periodTime.tv_sec != 0 or it->second.periodTime.tv_nsec != 0) + tmp.insert(std::pair( it->second.periodTime, it->second ) ); } m_users.erase( nextExpiration );