Fix another crash in Timer::Call

fixes #8550
This commit is contained in:
Gunnar Beutner 2015-02-28 08:43:49 +01:00
parent 4cc7d4963c
commit cd380a8494
4 changed files with 24 additions and 17 deletions

View File

@ -59,6 +59,9 @@ void StreamLogger::Stop(void)
*/
StreamLogger::~StreamLogger(void)
{
if (m_FlushLogTimer)
m_FlushLogTimer->Stop();
if (m_OwnsStream)
delete m_Stream;
}

View File

@ -58,10 +58,6 @@ Timer::Timer(void)
Timer::~Timer(void)
{
Stop();
boost::mutex::scoped_lock lock(l_TimerMutex);
while (m_Running)
l_TimerCV.wait(lock);
}
/**
@ -99,19 +95,12 @@ void Timer::Call(void)
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);
}
/**
@ -152,13 +141,13 @@ void Timer::Start(void)
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());
@ -172,20 +161,32 @@ void Timer::Stop(void)
/* 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)

View File

@ -45,7 +45,7 @@ public:
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;
@ -84,6 +84,7 @@ private:
bool m_Running; /**< Whether the timer proc is currently running. */
void Call();
void InternalReschedule(bool completed, double next = -1);
static void TimerThreadProc(void);

View File

@ -44,6 +44,8 @@ WorkQueue::WorkQueue(size_t maxItems, int threadCount)
WorkQueue::~WorkQueue(void)
{
m_StatusTimer->Stop();
Join(true);
}