diff options
author | Joerg Bornemann <joerg.bornemann@qt.io> | 2017-07-27 14:06:30 +0200 |
---|---|---|
committer | Joerg Bornemann <joerg.bornemann@qt.io> | 2017-07-30 19:11:49 +0000 |
commit | 85403d0af06a0728c9c6f1bd7a6f224949cd894e (patch) | |
tree | 2a769aedc41e65b51723f0d430e93a9a35c5d59e /tests/auto/corelib/kernel/qwineventnotifier | |
parent | 7b2debda2b7ea94b9ca272180d7cba68a18ca0c1 (diff) |
Support more than 62 instances of QWinEventNotifier, take 2
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.
Task-number: QTBUG-8819
Change-Id: I3061811c18e669becf9de603bbdd7ba96e4d2fcd
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@qt.io>
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
Diffstat (limited to 'tests/auto/corelib/kernel/qwineventnotifier')
-rw-r--r-- | tests/auto/corelib/kernel/qwineventnotifier/tst_qwineventnotifier.cpp | 88 |
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(¬ifier, &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" |