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

openSUSE Build Service is sponsored by