summaryrefslogtreecommitdiff
path: root/lib/common/Timer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/common/Timer.cpp')
-rw-r--r--lib/common/Timer.cpp99
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();
}