summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel
diff options
context:
space:
mode:
authorAlex Trotsenko <alex1973tr@gmail.com>2021-01-27 16:18:11 +0200
committerOswald Buddenhagen <oswald.buddenhagen@gmx.de>2021-01-29 10:55:42 +0000
commit8f9222db3b5976ac0977b9ed5f27744c24bd982e (patch)
treefd48cf9661085d923ee1835bbecbdefcaf0472cf /src/corelib/kernel
parentf9896cb3cdb884fbd98b0c60f55133b2e6c581d3 (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.cpp10
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;
}
}