diff options
Diffstat (limited to 'lib/common/Timer.cpp')
-rw-r--r-- | lib/common/Timer.cpp | 99 |
1 files changed, 48 insertions, 51 deletions
diff --git a/lib/common/Timer.cpp b/lib/common/Timer.cpp index ad6b5e8d..4f8c989e 100644 --- a/lib/common/Timer.cpp +++ b/lib/common/Timer.cpp @@ -55,8 +55,8 @@ void Timers::Init() sigemptyset(&newact.sa_mask); if (::sigaction(SIGALRM, &newact, &oldact) != 0) { - BOX_ERROR("Failed to install signal handler"); - THROW_EXCEPTION(CommonException, Internal); + THROW_SYS_ERROR("Failed to install signal handler", + CommonException, Internal); } ASSERT(oldact.sa_handler == 0); #endif // WIN32 && !PLATFORM_CYGWIN @@ -72,13 +72,23 @@ void Timers::Init() // Created: 6/11/2006 // // -------------------------------------------------------------------------- -void Timers::Cleanup() +void Timers::Cleanup(bool throw_exception_if_not_initialised) { - ASSERT(spTimers); - if (!spTimers) + if (throw_exception_if_not_initialised) { - BOX_ERROR("Tried to clean up timers when not initialised!"); - return; + ASSERT(spTimers); + if (!spTimers) + { + BOX_ERROR("Tried to clean up timers when not initialised!"); + return; + } + } + else + { + if (!spTimers) + { + return; + } } #if defined WIN32 && ! defined PLATFORM_CYGWIN @@ -87,8 +97,11 @@ void Timers::Cleanup() struct itimerval timeout; memset(&timeout, 0, sizeof(timeout)); - int result = ::setitimer(ITIMER_REAL, &timeout, NULL); - ASSERT(result == 0); + if(::setitimer(ITIMER_REAL, &timeout, NULL) != 0) + { + THROW_SYS_ERROR("Failed to set interval timer", + CommonException, Internal); + } struct sigaction newact, oldact; newact.sa_handler = SIG_DFL; @@ -96,8 +109,8 @@ void Timers::Cleanup() sigemptyset(&(newact.sa_mask)); if (::sigaction(SIGALRM, &newact, &oldact) != 0) { - BOX_ERROR("Failed to remove signal handler"); - THROW_EXCEPTION(CommonException, Internal); + THROW_SYS_ERROR("Failed to remove signal handler", + CommonException, Internal); } ASSERT(oldact.sa_handler == Timers::SignalHandler); #endif // WIN32 && !PLATFORM_CYGWIN @@ -118,7 +131,6 @@ void Timers::Cleanup() void Timers::Add(Timer& rTimer) { ASSERT(spTimers); - ASSERT(&rTimer); BOX_TRACE(TIMER_ID_OF(rTimer) " added to global queue, rescheduling"); spTimers->push_back(&rTimer); Reschedule(); @@ -135,8 +147,14 @@ void Timers::Add(Timer& rTimer) // -------------------------------------------------------------------------- void Timers::Remove(Timer& rTimer) { + if(!spTimers) + { + BOX_WARNING(TIMER_ID_OF(rTimer) " was still active after " + "timer subsystem was cleaned up, already removed."); + return; + } + ASSERT(spTimers); - ASSERT(&rTimer); BOX_TRACE(TIMER_ID_OF(rTimer) " removed from global queue, rescheduling"); bool restart = true; @@ -155,7 +173,7 @@ void Timers::Remove(Timer& rTimer) } } } - + Reschedule(); } @@ -185,26 +203,24 @@ void Timers::Reschedule() ASSERT(spTimers); if (spTimers == NULL) { - THROW_EXCEPTION(CommonException, Internal) + THROW_EXCEPTION(CommonException, TimersNotInitialised); } #ifndef WIN32 struct sigaction oldact; if (::sigaction(SIGALRM, NULL, &oldact) != 0) { - BOX_ERROR("Failed to check signal handler"); - THROW_EXCEPTION(CommonException, Internal) + THROW_SYS_ERROR("Failed to check signal handler", + CommonException, Internal); } ASSERT(oldact.sa_handler == Timers::SignalHandler); if (oldact.sa_handler != Timers::SignalHandler) { - BOX_ERROR("Signal handler was " << - (void *)oldact.sa_handler << - ", expected " << - (void *)Timers::SignalHandler); - THROW_EXCEPTION(CommonException, Internal) + THROW_EXCEPTION_MESSAGE(CommonException, Internal, + "Signal handler was " << (void *)oldact.sa_handler << + ", expected " << (void *)Timers::SignalHandler); } #endif @@ -218,6 +234,8 @@ void Timers::Reschedule() // win32 timers need no management #else box_time_t timeNow = GetCurrentBoxTime(); + int64_t timeToNextEvent; + std::string nameOfNextEvent; // scan for, trigger and remove expired timers. Removal requires // us to restart the scan each time, due to std::vector semantics. @@ -225,6 +243,7 @@ void Timers::Reschedule() while (restart) { restart = false; + timeToNextEvent = 0; for (std::vector<Timer*>::iterator i = spTimers->begin(); i != spTimers->end(); i++) @@ -252,35 +271,14 @@ void Timers::Reschedule() " seconds"); */ } - } - } - - // Now the only remaining timers should all be in the future. - // Scan to find the next one to fire (earliest deadline). - - int64_t timeToNextEvent = 0; - std::string nameOfNextEvent; - - for (std::vector<Timer*>::iterator i = spTimers->begin(); - i != spTimers->end(); i++) - { - Timer& rTimer = **i; - int64_t timeToExpiry = rTimer.GetExpiryTime() - timeNow; - ASSERT(timeToExpiry > 0) - if (timeToExpiry <= 0) - { - timeToExpiry = 1; - } - - if (timeToNextEvent == 0 || timeToNextEvent > timeToExpiry) - { - timeToNextEvent = timeToExpiry; - nameOfNextEvent = rTimer.GetName(); + if (timeToNextEvent == 0 || timeToNextEvent > timeToExpiry) + { + timeToNextEvent = timeToExpiry; + nameOfNextEvent = rTimer.GetName(); + } } } - - ASSERT(timeToNextEvent >= 0); if (timeToNextEvent == 0) { @@ -302,8 +300,8 @@ void Timers::Reschedule() if(::setitimer(ITIMER_REAL, &timeout, NULL) != 0) { - BOX_ERROR("Failed to initialise system timer\n"); - THROW_EXCEPTION(CommonException, Internal) + THROW_SYS_ERROR("Failed to initialise system timer", + CommonException, Internal); } #endif } @@ -322,7 +320,6 @@ void Timers::Reschedule() // -------------------------------------------------------------------------- void Timers::SignalHandler(int unused) { - // ASSERT(spTimers); Timers::RequestReschedule(); } |