summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/kernel/qwineventnotifier/tst_qwineventnotifier.cpp
diff options
context:
space:
mode:
authorJoerg Bornemann <joerg.bornemann@qt.io>2017-06-12 14:37:39 +0200
committerJoerg Bornemann <joerg.bornemann@qt.io>2017-06-26 05:05:38 +0000
commit5c6210e3452f78cab2f58887e747eb5cb2501f70 (patch)
treebc310dfa08032700155682f7b920c89ea6bd8a1d /tests/auto/corelib/kernel/qwineventnotifier/tst_qwineventnotifier.cpp
parent58d3a3eda271ad696d5df6f16b09bad97f9b54a1 (diff)
Support more than 62 instances of QWinEventNotifier
QWinEventNotifiers were limited to 62 instances, because of WaitForMultipleObject's limitation to MAXIMUM_WAIT_OBJECTS - 1 handles. Use the RegisterWaitForSingleObject API which does not have this restriction and executes waits in threads managed by the system. A central manual reset event per event dispatcher is signaled in the RegisterWaitForSingleObject callback and waited for in the event loop. [ChangeLog][QtCore][QWinEventNotifier] QWinEventNotifier is not restricted to 62 instances anymore. Task-number: QTBUG-8819 Change-Id: I2c749951453a4b699cc50dada0d6017440b67a4a Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
Diffstat (limited to 'tests/auto/corelib/kernel/qwineventnotifier/tst_qwineventnotifier.cpp')
-rw-r--r--tests/auto/corelib/kernel/qwineventnotifier/tst_qwineventnotifier.cpp88
1 files changed, 88 insertions, 0 deletions
diff --git a/tests/auto/corelib/kernel/qwineventnotifier/tst_qwineventnotifier.cpp b/tests/auto/corelib/kernel/qwineventnotifier/tst_qwineventnotifier.cpp
index 3221587300..304f6121a5 100644
--- a/tests/auto/corelib/kernel/qwineventnotifier/tst_qwineventnotifier.cpp
+++ b/tests/auto/corelib/kernel/qwineventnotifier/tst_qwineventnotifier.cpp
@@ -31,6 +31,8 @@
#include <qtimer.h>
#include <qt_windows.h>
+#include <memory>
+
class tst_QWinEventNotifier : public QObject
{
Q_OBJECT
@@ -40,6 +42,7 @@ protected slots:
void simple_timerSet();
private slots:
void simple();
+ void manyNotifiers();
private:
HANDLE simpleHEvent;
@@ -87,6 +90,91 @@ void tst_QWinEventNotifier::simple()
QVERIFY(simpleActivated);
}
+class EventWithNotifier : public QObject
+{
+ Q_OBJECT
+public:
+ EventWithNotifier()
+ {
+ connect(&notifier, &QWinEventNotifier::activated,
+ this, &EventWithNotifier::onNotifierActivated);
+ notifier.setHandle(CreateEvent(0, TRUE, FALSE, 0));
+ notifier.setEnabled(true);
+
+ static int nextIndex = 0;
+ idx = nextIndex++;
+ }
+
+ ~EventWithNotifier()
+ {
+ notifier.setEnabled(false);
+ CloseHandle(notifier.handle());
+ }
+
+ HANDLE eventHandle() const { return notifier.handle(); }
+ int numberOfTimesActivated() const { return activatedCount; }
+
+signals:
+ void activated();
+
+public slots:
+ void onNotifierActivated()
+ {
+ ResetEvent(notifier.handle());
+ activatedCount++;
+ emit activated();
+ }
+
+private:
+ QWinEventNotifier notifier;
+ int activatedCount = 0;
+ int idx = 0;
+};
+
+void tst_QWinEventNotifier::manyNotifiers()
+{
+ const size_t maxEvents = 100;
+ const size_t middleEvenEvent = maxEvents / 2;
+ Q_ASSERT(middleEvenEvent % 2 == 0);
+ using EventWithNotifierPtr = std::unique_ptr<EventWithNotifier>;
+ std::vector<EventWithNotifierPtr> events(maxEvents);
+ std::generate(events.begin(), events.end(), [] () {
+ return EventWithNotifierPtr(new EventWithNotifier);
+ });
+
+ QTestEventLoop loop;
+ auto connection = connect(events.at(8).get(), &EventWithNotifier::activated, &loop, &QTestEventLoop::exitLoop);
+ for (const auto &ewn : events) {
+ connect(ewn.get(), &EventWithNotifier::activated, [&events, &loop] () {
+ if (std::all_of(events.cbegin(), events.cend(),
+ [] (const EventWithNotifierPtr &ewn) {
+ return ewn->numberOfTimesActivated() > 0; })) {
+ loop.exitLoop();
+ }
+ });
+ }
+
+ // Activate all even events before running the event loop.
+ for (size_t i = 0; i < events.size(); i += 2)
+ SetEvent(events.at(i)->eventHandle());
+
+ // Wait until event notifier with index 8 has been activated.
+ loop.enterLoop(30);
+ QObject::disconnect(connection);
+
+ // Activate all odd events after the event loop has run for a bit.
+ for (size_t i = 1; i < events.size(); i += 2)
+ SetEvent(events.at(i)->eventHandle());
+
+ // Wait until all event notifiers have fired.
+ loop.enterLoop(30);
+
+ // All notifiers must have been activated exactly once.
+ QVERIFY(std::all_of(events.cbegin(), events.cend(), [] (const EventWithNotifierPtr &ewn) {
+ return ewn->numberOfTimesActivated() == 1;
+ }));
+}
+
QTEST_MAIN(tst_QWinEventNotifier)
#include "tst_qwineventnotifier.moc"