diff options
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_win.cpp | 4 | ||||
-rw-r--r-- | tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp | 26 |
2 files changed, 29 insertions, 1 deletions
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index 34518c4101..65fc7870f2 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -527,6 +527,7 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags) // QCoreApplication::sendPostedEvents() takes care about recursions. sendPostedEvents(); + auto threadData = d->threadData.loadRelaxed(); bool canWait; bool retVal = false; do { @@ -617,7 +618,8 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags) // still nothing - wait for message or signalled objects canWait = (!retVal && !d->interrupt.loadRelaxed() - && (flags & QEventLoop::WaitForMoreEvents)); + && flags.testFlag(QEventLoop::WaitForMoreEvents) + && threadData->canWaitLocked()); if (canWait) { emit aboutToBlock(); waitRet = MsgWaitForMultipleObjectsEx(nCount, pHandles, INFINITE, QS_ALLINPUT, MWMO_ALERTABLE | MWMO_INPUTAVAILABLE); 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 |