diff options
author | Alex Trotsenko <alex1973tr@gmail.com> | 2020-09-18 19:10:35 +0300 |
---|---|---|
committer | Alex Trotsenko <alex1973tr@gmail.com> | 2020-11-10 17:56:51 +0200 |
commit | aefd414ce2418bee5d6dacf9092f7a3949f02af8 (patch) | |
tree | e84181a5d423b98134ac878f6ac0787a7f477f53 /src/corelib/kernel/qeventdispatcher_win.cpp | |
parent | 0bfb39da858606a837f38f3d406f041a3f3c179c (diff) |
QWinEventNotifier: unlink from event dispatcher
Instead of multiplexing all notifications into a single Qt event for
the event dispatcher, we can send 'WinEventAct' event directly for each
notifier which activated. This trick improves the performance (esp.
on a large number of events) and allows us to remove notifiers handling
from the event dispatcher completely.
As an alternative to sending Qt events, use of Windows' APC queue in
conjunction with waking up the Qt event loop from within the Windows
thread pool has been considered. However, that would lead to signal
emission asynchronous to the Qt event loop's operation, which is not
acceptable.
Thanks to Oswald Buddenhagen for the proposed idea.
[ChangeLog][QtCore][QAbstractEventDispatcher] The
{un}registerEventNotifier() member functions have been removed.
QWinEventNotifier is no longer needed to be registered in the
event dispatcher.
Change-Id: I140892fb909eaae0eabf2e07ebabcab78c43841c
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
Diffstat (limited to 'src/corelib/kernel/qeventdispatcher_win.cpp')
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_win.cpp | 102 |
1 files changed, 1 insertions, 101 deletions
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index 44487d57e2..1336238795 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -47,12 +47,10 @@ #include "qset.h" #include "qsocketnotifier.h" #include "qvarlengtharray.h" -#include "qwineventnotifier.h" #include "qelapsedtimer.h" #include "qcoreapplication_p.h" #include <private/qthread_p.h> -#include <private/qwineventnotifier_p.h> QT_BEGIN_NAMESPACE @@ -99,7 +97,7 @@ LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPA QEventDispatcherWin32Private::QEventDispatcherWin32Private() : interrupt(false), internalHwnd(0), getMessageHook(0), sendPostedEventsTimerId(0), wakeUps(0), - activateNotifiersPosted(false), activateEventNotifiersPosted(false) + activateNotifiersPosted(false) { } @@ -109,12 +107,6 @@ QEventDispatcherWin32Private::~QEventDispatcherWin32Private() DestroyWindow(internalHwnd); } -void QEventDispatcherWin32Private::activateEventNotifier(QWinEventNotifier * wen) -{ - QEvent event(QEvent::WinEventAct); - QCoreApplication::sendEvent(wen, &event); -} - // This function is called by a workerthread void WINAPI QT_WIN_CALLBACK qt_fast_timer_proc(uint timerId, uint /*reserved*/, DWORD_PTR user, DWORD_PTR /*reserved*/, DWORD_PTR /*reserved*/) { @@ -455,14 +447,6 @@ void QEventDispatcherWin32Private::postActivateSocketNotifiers() activateNotifiersPosted = PostMessage(internalHwnd, WM_QT_ACTIVATENOTIFIERS, 0, 0); } -void QEventDispatcherWin32Private::postActivateEventNotifiers() -{ - Q_Q(QEventDispatcherWin32); - - if (!activateEventNotifiersPosted.fetchAndStoreRelease(true)) - QCoreApplication::postEvent(q, new QEvent(QEvent::WinEventAct)); -} - QEventDispatcherWin32::QEventDispatcherWin32(QObject *parent) : QEventDispatcherWin32(*new QEventDispatcherWin32Private, parent) { @@ -817,83 +801,6 @@ QEventDispatcherWin32::registeredTimers(QObject *object) const return list; } -bool QEventDispatcherWin32::registerEventNotifier(QWinEventNotifier *notifier) -{ - Q_ASSERT(notifier); -#ifndef QT_NO_DEBUG - if (notifier->thread() != thread() || thread() != QThread::currentThread()) { - qWarning("QEventDispatcherWin32: event notifiers cannot be enabled from another thread"); - return false; - } -#endif - - Q_D(QEventDispatcherWin32); - - if (d->winEventNotifierList.contains(notifier)) - return true; - - d->winEventNotifierList.append(notifier); - d->winEventNotifierListModified = true; - - return QWinEventNotifierPrivate::get(notifier)->registerWaitObject(); -} - -void QEventDispatcherWin32::unregisterEventNotifier(QWinEventNotifier *notifier) -{ - Q_ASSERT(notifier); -#ifndef QT_NO_DEBUG - if (notifier->thread() != thread() || thread() != QThread::currentThread()) { - qWarning("QEventDispatcherWin32: event notifiers cannot be disabled from another thread"); - return; - } -#endif - doUnregisterEventNotifier(notifier); -} - -void QEventDispatcherWin32::doUnregisterEventNotifier(QWinEventNotifier *notifier) -{ - Q_D(QEventDispatcherWin32); - - int i = d->winEventNotifierList.indexOf(notifier); - if (i == -1) - return; - d->winEventNotifierList.takeAt(i); - d->winEventNotifierListModified = true; - QWinEventNotifierPrivate *nd = QWinEventNotifierPrivate::get(notifier); - if (nd->waitHandle) - nd->unregisterWaitObject(); -} - -void QEventDispatcherWin32::activateEventNotifiers() -{ - Q_D(QEventDispatcherWin32); - - // Enable WM_QT_ACTIVATEWINEVENTS posting. - d->activateEventNotifiersPosted.fetchAndStoreAcquire(false); - - // Activate signaled notifiers. Our winEventNotifierList can be modified in activation slots. - do { - d->winEventNotifierListModified = false; - for (int i = 0; i < d->winEventNotifierList.count(); ++i) { - QWinEventNotifier *notifier = d->winEventNotifierList.at(i); - QWinEventNotifierPrivate *nd = QWinEventNotifierPrivate::get(notifier); - if (nd->signaled.loadRelaxed()) { - nd->signaled.storeRelaxed(false); - nd->unregisterWaitObject(); - d->activateEventNotifier(notifier); - } - } - } while (d->winEventNotifierListModified); - - // Re-register the remaining activated notifiers. - for (int i = 0; i < d->winEventNotifierList.count(); ++i) { - QWinEventNotifier *notifier = d->winEventNotifierList.at(i); - QWinEventNotifierPrivate *nd = QWinEventNotifierPrivate::get(notifier); - if (!nd->waitHandle) - nd->registerWaitObject(); - } -} - int QEventDispatcherWin32::remainingTime(int timerId) { #ifndef QT_NO_DEBUG @@ -958,10 +865,6 @@ void QEventDispatcherWin32::closingDown() doUnregisterSocketNotifier((*(d->sn_except.begin()))->obj); Q_ASSERT(d->active_fd.isEmpty()); - // clean up any eventnotifiers - while (!d->winEventNotifierList.isEmpty()) - doUnregisterEventNotifier(d->winEventNotifierList.first()); - // clean up any timers for (int i = 0; i < d->timerVec.count(); ++i) d->unregisterTimer(d->timerVec.at(i)); @@ -1009,9 +912,6 @@ bool QEventDispatcherWin32::event(QEvent *e) case QEvent::Timer: d->sendTimerEvent(static_cast<const QTimerEvent*>(e)->timerId()); break; - case QEvent::WinEventAct: - activateEventNotifiers(); - break; default: break; } |