diff options
author | Alex Trotsenko <alex1973tr@gmail.com> | 2021-01-27 16:18:11 +0200 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@gmx.de> | 2021-01-29 10:55:42 +0000 |
commit | 8f9222db3b5976ac0977b9ed5f27744c24bd982e (patch) | |
tree | fd48cf9661085d923ee1835bbecbdefcaf0472cf /src/corelib/kernel | |
parent | f9896cb3cdb884fbd98b0c60f55133b2e6c581d3 (diff) |
QEventDispatcherGlib: do not omit active notifiers on source dispatching
It is quite common for a socket notifier to be disabled in a slot
connected to its activated() signal. But the event dispatcher did not
update the position in the list of registered notifiers, which caused
the next notifier to be omitted. Of course, on the next iteration of
the event loop, the omitted notifier would fire again, but this reduced
the scalability of applications that use a large number of sockets.
To solve the problem, we update the current position in the list when
a notifier becomes unregistered.
Change-Id: I6565bf23500d9e38ce84b34784d89d227fa166e1
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_glib.cpp | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/src/corelib/kernel/qeventdispatcher_glib.cpp b/src/corelib/kernel/qeventdispatcher_glib.cpp index 59c937362b..86f6b0b4aa 100644 --- a/src/corelib/kernel/qeventdispatcher_glib.cpp +++ b/src/corelib/kernel/qeventdispatcher_glib.cpp @@ -62,6 +62,7 @@ struct GSocketNotifierSource { GSource source; QList<GPollFDWithQSocketNotifier *> pollfds; + int activeNotifierPos; }; static gboolean socketNotifierSourcePrepare(GSource *, gint *timeout) @@ -100,8 +101,9 @@ static gboolean socketNotifierSourceDispatch(GSource *source, GSourceFunc, gpoin QEvent event(QEvent::SockAct); GSocketNotifierSource *src = reinterpret_cast<GSocketNotifierSource *>(source); - for (int i = 0; i < src->pollfds.count(); ++i) { - GPollFDWithQSocketNotifier *p = src->pollfds.at(i); + for (src->activeNotifierPos = 0; src->activeNotifierPos < src->pollfds.count(); + ++src->activeNotifierPos) { + GPollFDWithQSocketNotifier *p = src->pollfds.at(src->activeNotifierPos); if ((p->pollfd.revents & p->pollfd.events) != 0) QCoreApplication::sendEvent(p->socketNotifier, &event); @@ -501,6 +503,10 @@ void QEventDispatcherGlib::unregisterSocketNotifier(QSocketNotifier *notifier) d->socketNotifierSource->pollfds.removeAt(i); delete p; + // Keep a position in the list for the next item. + if (i <= d->socketNotifierSource->activeNotifierPos) + --d->socketNotifierSource->activeNotifierPos; + return; } } |