Timer::~Timer(void)
{
Stop();
-
- boost::mutex::scoped_lock lock(l_TimerMutex);
- while (m_Running)
- l_TimerCV.wait(lock);
}
/**
try {
OnTimerExpired(Timer::Ptr(this));
} catch (...) {
- Reschedule();
+ InternalReschedule(true);
throw;
}
- {
- boost::mutex::scoped_lock lock(l_TimerMutex);
- m_Running = false;
- l_TimerCV.notify_all();
- }
-
- Reschedule();
-
+ InternalReschedule(true);
}
/**
m_Started = true;
}
- Reschedule();
+ InternalReschedule(false);
}
/**
* Unregisters the timer and stops processing events for it.
*/
-void Timer::Stop(void)
+void Timer::Stop(bool wait)
{
ASSERT(!OwnsLock());
/* Notify the worker thread that we've disabled a timer. */
l_TimerCV.notify_all();
+
+ while (wait && m_Running)
+ l_TimerCV.wait(lock);
+}
+
+void Timer::Reschedule(double next)
+{
+ InternalReschedule(false, next);
}
/**
* Reschedules this timer.
*
+ * @param completed Whether the timer has just completed its callback.
* @param next The time when this timer should be called again. Use -1 to let
* the timer figure out a suitable time based on the interval.
*/
-void Timer::Reschedule(double next)
+void Timer::InternalReschedule(bool completed, double next)
{
ASSERT(!OwnsLock());
boost::mutex::scoped_lock lock(l_TimerMutex);
+ if (completed)
+ m_Running = false;
+
if (next < 0) {
/* Don't schedule the next call if this is not a periodic timer. */
if (m_Interval <= 0)
static void AdjustTimers(double adjustment);
void Start(void);
- void Stop(void);
+ void Stop(bool wait = false);
void Reschedule(double next = -1);
double GetNext(void) const;
bool m_Running; /**< Whether the timer proc is currently running. */
void Call();
+ void InternalReschedule(bool completed, double next = -1);
static void TimerThreadProc(void);