summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorAlex Trotsenko <alex1973tr@gmail.com>2019-11-16 20:39:20 +0200
committerAlex Trotsenko <alex1973tr@gmail.com>2020-07-29 18:34:34 +0300
commit8969070cfdeab4502a693bdf46a572cbea50bab3 (patch)
tree32b145683044e02725a16cb6adba57d7d4346643 /tests
parent9d55d6b45bfc1f4e3c603bcc95f694ebe3a9206f (diff)
QEventDispatcherWin32: redesign event notifiers activation
The previous implementation multiplexed callback-based event notification into a single proxy event (cf. 85403d0af), which was in turn object-waited for (this was the case since the beginning of public qt history). It makes more sense to multiplex into a posted message, because that also works with foreign event loops that do not know anything about our event objects. Task-number: QTBUG-64443 Change-Id: I97945ac8b5d7c8582701077134c0aef4f3b5a18f Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/gui/kernel/noqteventloop/tst_noqteventloop.cpp83
1 files changed, 83 insertions, 0 deletions
diff --git a/tests/auto/gui/kernel/noqteventloop/tst_noqteventloop.cpp b/tests/auto/gui/kernel/noqteventloop/tst_noqteventloop.cpp
index 5fd7079a6a..6f2ed47b72 100644
--- a/tests/auto/gui/kernel/noqteventloop/tst_noqteventloop.cpp
+++ b/tests/auto/gui/kernel/noqteventloop/tst_noqteventloop.cpp
@@ -37,6 +37,7 @@
#include <QtNetwork/qtcpsocket.h>
#include <QtCore/qelapsedtimer.h>
#include <QtCore/qtimer.h>
+#include <QtCore/qwineventnotifier.h>
#include <QtCore/qt_windows.h>
@@ -50,6 +51,8 @@ class tst_NoQtEventLoop : public QObject
private slots:
void consumeMouseEvents();
void consumeSocketEvents();
+ void consumeWinEvents_data();
+ void consumeWinEvents();
void deliverEventsInLivelock();
void postingWithNoYieldFlag();
};
@@ -314,6 +317,86 @@ void tst_NoQtEventLoop::consumeSocketEvents()
QVERIFY(server.hasPendingConnections());
}
+void tst_NoQtEventLoop::consumeWinEvents_data()
+{
+ QTest::addColumn<bool>("peeking");
+ QTest::addColumn<bool>("nestedLoops");
+ QTest::addColumn<bool>("nativeMainLoop");
+
+ QTest::newRow("PeekMessage, single loop") << true << false << true;
+ QTest::newRow("GetMessage, single loop") << false << false << true;
+
+ QTest::newRow("PeekMessage, nested loops") << true << true << true;
+ QTest::newRow("GetMessage, nested loops") << false << true << true;
+ QTest::newRow("PeekMessage, nested loops, Qt main loop") << true << true << false;
+ QTest::newRow("GetMessage, nested loops, Qt main loop") << false << true << false;
+}
+
+void tst_NoQtEventLoop::consumeWinEvents()
+{
+ QFETCH(bool, peeking);
+ QFETCH(bool, nestedLoops);
+ QFETCH(bool, nativeMainLoop);
+ int argc = 1;
+ char *argv[] = { const_cast<char *>("test"), 0 };
+ QGuiApplication app(argc, argv);
+
+ HANDLE winEvent = ::CreateEvent(0, FALSE, FALSE, 0);
+ QVERIFY(winEvent != NULL);
+ bool notifierActivated = false;
+ QWinEventNotifier notifier(winEvent);
+ connect(&notifier, &QWinEventNotifier::activated, [&notifierActivated]() {
+ notifierActivated = true;
+ });
+
+ bool timeExpired = false;
+ QTimer expiredTimer;
+ connect(&expiredTimer, &QTimer::timeout, [&timeExpired]() {
+ timeExpired = true;
+ });
+ expiredTimer.start(3000);
+
+ auto runNativeEventLoop = [&timeExpired, &notifierActivated, peeking]() -> void {
+ MSG msg;
+ while (!(timeExpired || notifierActivated)) {
+ if (peeking) {
+ if (!::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
+ QThread::msleep(100);
+ continue;
+ }
+ } else {
+ if (::GetMessage(&msg, NULL, 0, 0) <= 0)
+ break;
+ }
+
+ ::TranslateMessage(&msg);
+ ::DispatchMessage(&msg);
+ }
+ };
+
+ QTimer::singleShot(0, [winEvent, nestedLoops, runNativeEventLoop]() {
+ ::SetEvent(winEvent);
+ if (nestedLoops)
+ runNativeEventLoop();
+ });
+
+ // Exec main message loop
+ if (nativeMainLoop) {
+ runNativeEventLoop();
+ } else {
+ QEventLoop loop;
+ connect(&notifier, &QWinEventNotifier::activated,
+ &loop, &QEventLoop::quit);
+ connect(&expiredTimer, &QTimer::timeout,
+ &loop, &QEventLoop::quit);
+
+ loop.exec();
+ }
+
+ QVERIFY(notifierActivated);
+ QVERIFY(!timeExpired);
+}
+
void tst_NoQtEventLoop::deliverEventsInLivelock()
{
int argc = 1;