fixed GH #2058: Synchronization issue in Poco::Util::Timer at destruction

This commit is contained in:
Günter Obiltschnig
2018-03-06 17:33:02 +01:00
parent f352f61e5b
commit d73bb2ea86
3 changed files with 86 additions and 33 deletions

View File

@@ -32,18 +32,18 @@ public:
_queue(queue)
{
}
~TimerNotification()
{
}
virtual bool execute() = 0;
Poco::TimedNotificationQueue& queue()
{
return _queue;
}
private:
Poco::TimedNotificationQueue& _queue;
};
@@ -56,11 +56,11 @@ public:
TimerNotification(queue)
{
}
~StopNotification()
{
}
bool execute()
{
queue().clear();
@@ -76,23 +76,36 @@ public:
TimerNotification(queue)
{
}
~CancelNotification()
{
}
bool execute()
{
// Check if there's a StopNotification pending.
Poco::AutoPtr<TimerNotification> pNf = static_cast<TimerNotification*>(queue().dequeueNotification());
while (pNf)
{
if (pNf.cast<StopNotification>())
{
queue().clear();
_finished.set();
return false;
}
pNf = static_cast<TimerNotification*>(queue().dequeueNotification());
}
queue().clear();
_finished.set();
return true;
}
void wait()
{
_finished.wait();
}
private:
Poco::Event _finished;
};
@@ -106,16 +119,16 @@ public:
_pTask(pTask)
{
}
~TaskNotification()
{
}
TimerTask::Ptr task()
{
return _pTask;
return _pTask;
}
bool execute()
{
if (!_pTask->isCancelled())
@@ -140,7 +153,7 @@ public:
}
return true;
}
private:
TimerTask::Ptr _pTask;
};
@@ -154,13 +167,13 @@ public:
_interval(interval)
{
}
~PeriodicTaskNotification()
{
}
bool execute()
{
{
TaskNotification::execute();
if (!task()->isCancelled())
@@ -172,9 +185,9 @@ public:
queue().enqueueNotification(this, nextExecution);
duplicate();
}
return true;
return true;
}
private:
long _interval;
};
@@ -189,13 +202,13 @@ public:
_nextExecution(clock)
{
}
~FixedRateTaskNotification()
{
}
bool execute()
{
{
TaskNotification::execute();
if (!task()->isCancelled())
@@ -206,9 +219,9 @@ public:
queue().enqueueNotification(this, _nextExecution);
duplicate();
}
return true;
return true;
}
private:
long _interval;
Poco::Clock _nextExecution;
@@ -241,7 +254,7 @@ Timer::~Timer()
}
}
void Timer::cancel(bool wait)
{
Poco::AutoPtr<CancelNotification> pNf = new CancelNotification(_queue);
@@ -266,7 +279,7 @@ void Timer::schedule(TimerTask::Ptr pTask, Poco::Clock clock)
_queue.enqueueNotification(new TaskNotification(_queue, pTask), clock);
}
void Timer::schedule(TimerTask::Ptr pTask, long delay, long interval)
{
Poco::Clock clock;
@@ -288,7 +301,7 @@ void Timer::schedule(TimerTask::Ptr pTask, Poco::Clock clock, long interval)
_queue.enqueueNotification(new PeriodicTaskNotification(_queue, pTask, interval), clock);
}
void Timer::scheduleAtFixedRate(TimerTask::Ptr pTask, long delay, long interval)
{
Poco::Clock clock;