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) StreamLogger::~StreamLogger(void)
{ {
if (m_FlushLogTimer)
m_FlushLogTimer->Stop();
if (m_OwnsStream) if (m_OwnsStream)
delete m_Stream; delete m_Stream;
} }

View File

@ -58,10 +58,6 @@ Timer::Timer(void)
Timer::~Timer(void) Timer::~Timer(void)
{ {
Stop(); Stop();
boost::mutex::scoped_lock lock(l_TimerMutex);
while (m_Running)
l_TimerCV.wait(lock);
} }
/** /**
@ -99,19 +95,12 @@ void Timer::Call(void)
try { try {
OnTimerExpired(Timer::Ptr(this)); OnTimerExpired(Timer::Ptr(this));
} catch (...) { } catch (...) {
Reschedule(); InternalReschedule(true);
throw; throw;
} }
{ InternalReschedule(true);
boost::mutex::scoped_lock lock(l_TimerMutex);
m_Running = false;
l_TimerCV.notify_all();
}
Reschedule();
} }
/** /**
@ -152,13 +141,13 @@ void Timer::Start(void)
m_Started = true; m_Started = true;
} }
Reschedule(); InternalReschedule(false);
} }
/** /**
* Unregisters the timer and stops processing events for it. * Unregisters the timer and stops processing events for it.
*/ */
void Timer::Stop(void) void Timer::Stop(bool wait)
{ {
ASSERT(!OwnsLock()); ASSERT(!OwnsLock());
@ -172,20 +161,32 @@ void Timer::Stop(void)
/* Notify the worker thread that we've disabled a timer. */ /* Notify the worker thread that we've disabled a timer. */
l_TimerCV.notify_all(); l_TimerCV.notify_all();
while (wait && m_Running)
l_TimerCV.wait(lock);
}
void Timer::Reschedule(double next)
{
InternalReschedule(false, next);
} }
/** /**
* Reschedules this timer. * 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 * @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. * 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()); ASSERT(!OwnsLock());
boost::mutex::scoped_lock lock(l_TimerMutex); boost::mutex::scoped_lock lock(l_TimerMutex);
if (completed)
m_Running = false;
if (next < 0) { if (next < 0) {
/* Don't schedule the next call if this is not a periodic timer. */ /* Don't schedule the next call if this is not a periodic timer. */
if (m_Interval <= 0) if (m_Interval <= 0)

View File

@ -45,7 +45,7 @@ public:
static void AdjustTimers(double adjustment); static void AdjustTimers(double adjustment);
void Start(void); void Start(void);
void Stop(void); void Stop(bool wait = false);
void Reschedule(double next = -1); void Reschedule(double next = -1);
double GetNext(void) const; double GetNext(void) const;
@ -84,6 +84,7 @@ private:
bool m_Running; /**< Whether the timer proc is currently running. */ bool m_Running; /**< Whether the timer proc is currently running. */
void Call(); void Call();
void InternalReschedule(bool completed, double next = -1);
static void TimerThreadProc(void); static void TimerThreadProc(void);

View File

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