From fb6f62354ff8d29152db7cfa479b2689a25ae7a9 Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Tue, 18 Aug 2020 15:07:38 +0300 Subject: Synchronize QEventDispatcherWin32::processEvents() with QCoreApplication QCoreApplication has a special internal mechanism to control whether the event dispatcher should block after delivering the posted events. To handle queued connections in nested loops properly, we should use that functionality. Fixes: QTBUG-85981 Change-Id: I124179a23b26a995cf95ed379e97bfa62c95f42a Reviewed-by: Friedemann Kleint Reviewed-by: Oswald Buddenhagen Reviewed-by: Volker Hilsheimer (cherry picked from commit fe4b246446f721085946e399b96a42eccfcecca8) Reviewed-by: Qt Cherry-pick Bot --- .../qeventdispatcher/tst_qeventdispatcher.cpp | 26 ++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp b/tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp index 85a2dae3b6..7aadd14466 100644 --- a/tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp +++ b/tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp @@ -67,6 +67,7 @@ private slots: void sendPostedEvents_data(); void sendPostedEvents(); void processEventsOnlySendsQueuedEvents(); + void postedEventsPingPong(); void eventLoopExit(); }; @@ -349,6 +350,31 @@ void tst_QEventDispatcher::processEventsOnlySendsQueuedEvents() QCOMPARE(object.eventsReceived, 4); } +void tst_QEventDispatcher::postedEventsPingPong() +{ + QEventLoop mainLoop; + + // We need to have at least two levels of nested loops + // for the posted event to get stuck (QTBUG-85981). + QMetaObject::invokeMethod(this, [this, &mainLoop]() { + QMetaObject::invokeMethod(this, [&mainLoop]() { + // QEventLoop::quit() should be invoked on the next + // iteration of mainLoop.exec(). + QMetaObject::invokeMethod(&mainLoop, &QEventLoop::quit, + Qt::QueuedConnection); + }, Qt::QueuedConnection); + mainLoop.processEvents(); + }, Qt::QueuedConnection); + + // We should use Qt::CoarseTimer on Windows, to prevent event + // dispatcher from sending a posted event. + QTimer::singleShot(500, Qt::CoarseTimer, [&mainLoop]() { + mainLoop.exit(1); + }); + + QCOMPARE(mainLoop.exec(), 0); +} + void tst_QEventDispatcher::eventLoopExit() { // This test was inspired by QTBUG-79477. A particular -- cgit v1.2.3