mirror of
https://github.com/pocoproject/poco.git
synced 2025-04-27 18:30:51 +02:00
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:
commit
091c1af26a
@ -93,6 +93,11 @@ public:
|
|||||||
_finished.set();
|
_finished.set();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
Poco::AutoPtr<CancelNotification> pCnf = pNf.cast<CancelNotification>();
|
||||||
|
if (pCnf)
|
||||||
|
{
|
||||||
|
pCnf->_finished.set();
|
||||||
|
}
|
||||||
pNf = static_cast<TimerNotification*>(queue().dequeueNotification());
|
pNf = static_cast<TimerNotification*>(queue().dequeueNotification());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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()
|
void TimerTest::testFunc()
|
||||||
{
|
{
|
||||||
Timer timer;
|
Timer timer;
|
||||||
@ -305,6 +334,7 @@ CppUnit::Test* TimerTest::suite()
|
|||||||
CppUnit_addTest(pSuite, TimerTest, testCancel);
|
CppUnit_addTest(pSuite, TimerTest, testCancel);
|
||||||
CppUnit_addTest(pSuite, TimerTest, testCancelAllStop);
|
CppUnit_addTest(pSuite, TimerTest, testCancelAllStop);
|
||||||
CppUnit_addTest(pSuite, TimerTest, testCancelAllWaitStop);
|
CppUnit_addTest(pSuite, TimerTest, testCancelAllWaitStop);
|
||||||
|
CppUnit_addTest(pSuite, TimerTest, testMultiCancelAllWaitStop);
|
||||||
CppUnit_addTest(pSuite, TimerTest, testFunc);
|
CppUnit_addTest(pSuite, TimerTest, testFunc);
|
||||||
|
|
||||||
return pSuite;
|
return pSuite;
|
||||||
|
@ -35,6 +35,7 @@ public:
|
|||||||
void testCancel();
|
void testCancel();
|
||||||
void testCancelAllStop();
|
void testCancelAllStop();
|
||||||
void testCancelAllWaitStop();
|
void testCancelAllWaitStop();
|
||||||
|
void testMultiCancelAllWaitStop();
|
||||||
void testFunc();
|
void testFunc();
|
||||||
|
|
||||||
void setUp();
|
void setUp();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user