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 /src/corelib/kernel/qwineventnotifier.cpp | |
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 'src/corelib/kernel/qwineventnotifier.cpp')
-rw-r--r-- | src/corelib/kernel/qwineventnotifier.cpp | 60 |
1 files changed, 46 insertions, 14 deletions
diff --git a/src/corelib/kernel/qwineventnotifier.cpp b/src/corelib/kernel/qwineventnotifier.cpp index 0808374a6a..6bfa6ca729 100644 --- a/src/corelib/kernel/qwineventnotifier.cpp +++ b/src/corelib/kernel/qwineventnotifier.cpp @@ -37,7 +37,7 @@ ** ****************************************************************************/ -#include "qwineventnotifier.h" +#include "qwineventnotifier_p.h" #ifdef Q_OS_WINRT #include "qeventdispatcher_winrt_p.h" @@ -50,19 +50,6 @@ QT_BEGIN_NAMESPACE -class QWinEventNotifierPrivate : public QObjectPrivate -{ - Q_DECLARE_PUBLIC(QWinEventNotifier) -public: - QWinEventNotifierPrivate() - : handleToEvent(0), enabled(false) {} - QWinEventNotifierPrivate(HANDLE h, bool e) - : handleToEvent(h), enabled(e) {} - - HANDLE handleToEvent; - bool enabled; -}; - /*! \class QWinEventNotifier \inmodule QtCore @@ -246,4 +233,49 @@ bool QWinEventNotifier::event(QEvent * e) return false; } +#if defined(Q_OS_WINRT) + +bool QWinEventNotifierPrivate::registerWaitObject() +{ + Q_UNIMPLEMENTED(); + return false; +} + +void QWinEventNotifierPrivate::unregisterWaitObject() +{ + Q_UNIMPLEMENTED(); +} + +#else // defined(Q_OS_WINRT) + +static void CALLBACK wfsoCallback(void *context, BOOLEAN /*ignore*/) +{ + QWinEventNotifierPrivate *nd = reinterpret_cast<QWinEventNotifierPrivate *>(context); + QAbstractEventDispatcher *eventDispatcher = nd->threadData->eventDispatcher.load(); + QEventDispatcherWin32Private *edp = QEventDispatcherWin32Private::get( + static_cast<QEventDispatcherWin32 *>(eventDispatcher)); + SetEvent(edp->winEventNotifierActivatedEvent); +} + +bool QWinEventNotifierPrivate::registerWaitObject() +{ + if (RegisterWaitForSingleObject(&waitHandle, handleToEvent, wfsoCallback, this, + INFINITE, WT_EXECUTEONLYONCE) == 0) { + qErrnoWarning("QWinEventNotifier: RegisterWaitForSingleObject failed."); + return false; + } + return true; +} + +void QWinEventNotifierPrivate::unregisterWaitObject() +{ + // Unregister the wait handle and wait for pending callbacks to finish. + if (UnregisterWaitEx(waitHandle, INVALID_HANDLE_VALUE)) + waitHandle = NULL; + else + qErrnoWarning("QWinEventNotifier: UnregisterWaitEx failed."); +} + +#endif // !defined(Q_OS_WINRT) + QT_END_NAMESPACE |