aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2023-06-26 11:02:56 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2023-06-28 07:19:38 +0000
commitafffc5838523595ac1625c5e4ae27b99f7e24557 (patch)
treefce0733bfaf5712e6bc3f18ae40d5da2433d8456
parent7222d8a0470eaa254128b3207a2c295025dd1819 (diff)
PySide6/SignalManager: Fix memory leaks connecting free methods/lambdas
Change 1270a9e82e5bc3bd53a1131698ece60403da1192 changed the deletion of global receivers from listening to QObject::destroyed() (which caused thread issues) to using QPointer<> and purging the lists in notify. What is missing was the deletion of global receivers that are not tied by weak reference to a Python instance. Add a check in notify() to clean out the empty global receivers. Fixes: PYSIDE-2371 Fixes: PYSIDE-2299 Task-number: PYSIDE-2141 Change-Id: I39dca2a21088930c9a7f8e5eb7e948b3fff49b4b Reviewed-by: Christian Tismer <tismer@stackless.com> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> (cherry picked from commit 46ab90a5f9493ba0687834e6fa83413ca2437ce5) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--build_history/blacklist.txt4
-rw-r--r--sources/pyside6/libpyside/signalmanager.cpp19
2 files changed, 19 insertions, 4 deletions
diff --git a/build_history/blacklist.txt b/build_history/blacklist.txt
index 1da2b0ca0..475e5d40e 100644
--- a/build_history/blacklist.txt
+++ b/build_history/blacklist.txt
@@ -6,10 +6,6 @@
linux
darwin
win32
-[signals::anonymous_slot_leak_test]
- linux
- darwin
- win32
[Qt3DExtras::qt3dextras_test]
win32 ci
linux
diff --git a/sources/pyside6/libpyside/signalmanager.cpp b/sources/pyside6/libpyside/signalmanager.cpp
index 753b50557..aa20c23d6 100644
--- a/sources/pyside6/libpyside/signalmanager.cpp
+++ b/sources/pyside6/libpyside/signalmanager.cpp
@@ -210,6 +210,7 @@ struct SignalManager::SignalManagerPrivate
void deleteGobalReceiver(const QObject *gr);
void clear();
+ void purgeEmptyGobalReceivers();
GlobalReceiverV2Map m_globalReceivers;
static SignalManager::QmlMetaCallErrorHandler m_qmlMetaCallErrorHandler;
@@ -307,6 +308,7 @@ QObject *SignalManager::globalReceiver(QObject *sender, PyObject *callback, QObj
void SignalManager::notifyGlobalReceiver(QObject *receiver)
{
reinterpret_cast<GlobalReceiverV2 *>(receiver)->notify();
+ m_d->purgeEmptyGobalReceivers();
}
void SignalManager::releaseGlobalReceiver(const QObject *source, QObject *receiver)
@@ -342,6 +344,23 @@ void SignalManager::SignalManagerPrivate::clear()
m_globalReceivers.erase(m_globalReceivers.cbegin());
}
+static bool isEmptyGlobalReceiver(const GlobalReceiverV2Ptr &g)
+{
+ return g->isEmpty();
+}
+
+void SignalManager::SignalManagerPrivate::purgeEmptyGobalReceivers()
+{
+ // Delete repetitively (see comment in clear()).
+ while (true) {
+ auto it = std::find_if(m_globalReceivers.cbegin(), m_globalReceivers.cend(),
+ isEmptyGlobalReceiver);
+ if (it == m_globalReceivers.cend())
+ break;
+ m_globalReceivers.erase(it);
+ }
+}
+
int SignalManager::globalReceiverSlotIndex(QObject *receiver, const char *signature) const
{
return static_cast<GlobalReceiverV2 *>(receiver)->addSlot(signature);