Merge pull request #3920 from vojinilic/fixDeadlockInTimer

Fix deadlock in Timer when one sync and one async cancel requests are issued
This commit is contained in:
Günter Obiltschnig 2023-01-17 15:26:11 +01:00 committed by GitHub
commit 091c1af26a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 36 additions and 0 deletions

View File

@ -93,6 +93,11 @@ public:
_finished.set();
return false;
}
Poco::AutoPtr<CancelNotification> pCnf = pNf.cast<CancelNotification>();
if (pCnf)
{
pCnf->_finished.set();
}
pNf = static_cast<TimerNotification*>(queue().dequeueNotification());
}

View File

@ -260,6 +260,35 @@ void TimerTest::testCancelAllWaitStop()
}
void TimerTest::testMultiCancelAllWaitStop()
{
Timer timer;
// We will schedule a task and wait for it to start.
// After that we will schedule 2 cancel Notifications, one async and the other sync.
// But we want to make sure that both are scheduled and present in internal queue, thus we need to wait for this
// first task to start.
Poco::Event startEvent;
Poco::Event canceledScheduledEvent;
timer.schedule(Timer::func([&startEvent, &canceledScheduledEvent]()
{
startEvent.set();
canceledScheduledEvent.wait();
Poco::Thread::sleep(100);
}), Poco::Clock());
// We wait for simple task to start.
startEvent.wait();
// Schedule async cancel notification.
timer.cancel();
// Now allow simple task to proceed to sleep, in other words give time for next cancel to block.
canceledScheduledEvent.set();
// Schedule sync cancel, now we should have 2 cancel notifications in internal queue.
timer.cancel(true);
assertTrue (true); // don't hang
}
void TimerTest::testFunc()
{
Timer timer;
@ -305,6 +334,7 @@ CppUnit::Test* TimerTest::suite()
CppUnit_addTest(pSuite, TimerTest, testCancel);
CppUnit_addTest(pSuite, TimerTest, testCancelAllStop);
CppUnit_addTest(pSuite, TimerTest, testCancelAllWaitStop);
CppUnit_addTest(pSuite, TimerTest, testMultiCancelAllWaitStop);
CppUnit_addTest(pSuite, TimerTest, testFunc);
return pSuite;

View File

@ -35,6 +35,7 @@ public:
void testCancel();
void testCancelAllStop();
void testCancelAllWaitStop();
void testMultiCancelAllWaitStop();
void testFunc();
void setUp();