File 0001-Replace-disconnect-reconnect-with-recursion-detectio.patch of Package akonadi-server
From a4d918909035b352e393fed39e7c07790c6d72e5 Mon Sep 17 00:00:00 2001
From: Fabian Vogt <fabian@ritter-vogt.de>
Date: Wed, 3 Mar 2021 22:10:46 +0100
Subject: [PATCH] Replace disconnect+reconnect with recursion detection
Before Qt 5.14, QObject::disconnect within a slot can't perform cleanup,
continually decreasing performance (QTBUG-72649).
---
src/core/connection.cpp | 18 ++++++++++--------
src/core/connection_p.h | 1 +
2 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/src/core/connection.cpp b/src/core/connection.cpp
index 3e44c29f9..f1fd6fa82 100644
--- a/src/core/connection.cpp
+++ b/src/core/connection.cpp
@@ -31,6 +31,7 @@
#include <QApplication>
#include <QDateTime>
#include <QTimer>
+#include <QScopeGuard>
#include <private/protocol_exception_p.h>
#include <private/standarddirs_p.h>
@@ -180,7 +181,6 @@ void Connection::doReconnect()
Q_EMIT socketDisconnected();
});
connect(mSocket.data(), &QLocalSocket::disconnected, this, &Connection::socketDisconnected);
- // note: we temporarily disconnect from readyRead-signal inside handleIncomingData()
connect(mSocket.data(), &QLocalSocket::readyRead, this, &Connection::handleIncomingData);
// actually do connect
@@ -249,15 +249,20 @@ void Connection::handleIncomingData()
return;
}
+ // avoid re-entering this function when we call
+ // waitForData() deep inside Protocol::deserialize
+ if (m_inHandleIncomingData) {
+ return;
+ }
+
+ m_inHandleIncomingData = true;
+ auto resetRecursion = qScopeGuard([this] { m_inHandleIncomingData = false; });
+
while (mSocket->bytesAvailable() >= int(sizeof(qint64))) {
Protocol::DataStream stream(mSocket.data());
qint64 tag;
stream >> tag;
- // temporarily disconnect from readyRead-signal to avoid re-entering this function when we
- // call waitForData() deep inside Protocol::deserialize
- disconnect(mSocket.data(), &QLocalSocket::readyRead, this, &Connection::handleIncomingData);
-
Protocol::CommandPtr cmd;
try {
cmd = Protocol::deserialize(mSocket.data());
@@ -266,9 +271,6 @@ void Connection::handleIncomingData()
// cmd's type will be Invalid by default, so fall-through
}
- // reconnect to the signal again
- connect(mSocket.data(), &QLocalSocket::readyRead, this, &Connection::handleIncomingData);
-
if (!cmd || (cmd->type() == Protocol::Command::Invalid)) {
qCWarning(AKONADICORE_LOG) << "Invalid command, the world is going to end!";
mSocket->close();
diff --git a/src/core/connection_p.h b/src/core/connection_p.h
index 76d590cce..68c478522 100644
--- a/src/core/connection_p.h
+++ b/src/core/connection_p.h
@@ -86,6 +86,7 @@ private:
QFile *mLogFile = nullptr;
QByteArray mSessionId;
CommandBuffer *mCommandBuffer;
+ bool m_inHandleIncomingData = false;
friend class Akonadi::SessionThread;
};
--
2.25.1