Win32: always allow the event loop to be woken up by posted events

We set the wakeUps atomic to prevent multiple WM_QT_SENDPOSTEDEVENTS from
being posted. However, this might happen right after the event processing
thread cleared the atomic, but before it processed the previous
WM_QT_SENDPOSTEDEVENTS message. In that case, we end up with a set
atomic  and an empty event queue, resulting in the event loop to block
even though there are posted QEvents.

To prevent that, always reset the atomic when we handle the
WM_QT_SENDPOSTEDEVENTS message. In that case, we either call
sendPostedEvents, or startPostedEventsTimer. The former already resets
wakeUps; reset it in the latter as well.

Fixes: QTBUG-99323
Pick-to: 6.2 6.3 5.15
Change-Id: I931c02be9c42b02e8ca20daba5059cd8185f0a37
Reviewed-by: Alex Trotsenko <alex1973tr@gmail.com>
bb10
Volker Hilsheimer 2021-12-20 18:41:26 +01:00
parent d292f0143f
commit d671bab0e3
2 changed files with 2 additions and 3 deletions

View File

@ -249,6 +249,8 @@ LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPA
void QEventDispatcherWin32Private::startPostedEventsTimer()
{
// we received WM_QT_SENDPOSTEDEVENTS, so allow posting it again
wakeUps.storeRelaxed(0);
if (sendPostedEventsTimerId == 0) {
// Start a timer to deliver posted events when the message queue is emptied.
sendPostedEventsTimerId = SetTimer(internalHwnd, SendPostedEventsTimerId,

View File

@ -397,9 +397,6 @@ void tst_QEventDispatcher::postEventFromThread()
}
done = true;
if (QAbstractEventDispatcher::instance()->inherits("QEventDispatcherWin32"))
QEXPECT_FAIL("", QAbstractEventDispatcher::instance()->metaObject()->className(), Continue);
QVERIFY(!hadToQuit);
QVERIFY(threadPool->waitForDone());
}