From 24f39fa500fc01dd657c17d1fffc9dba7969ca6a Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 21 Mar 2024 11:48:20 +0100 Subject: libpyside: Clean up lambdas connected to signals earlier in shutdown Run a signal handler cleanup in CoreApplication::aboutToQuit() already before the general cleanup. This prevents them from leaking out of a main() function, for example. Task-number: PYSIDE-2646 Pick-to: 6.5 Change-Id: I87cce8d131c40c02b44b0102b3774477676b8f89 Reviewed-by: Christian Tismer (cherry picked from commit 47d6abbd727d193158cdc1747cb18241267409c1) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 16bedacb16dd52a7a3d6a09fca8623aaaa965c70) --- sources/pyside6/libpyside/signalmanager.cpp | 21 ++++++++++++++++++++- sources/pyside6/libpyside/signalmanager.h | 1 + 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/sources/pyside6/libpyside/signalmanager.cpp b/sources/pyside6/libpyside/signalmanager.cpp index b46761284..bb3453bad 100644 --- a/sources/pyside6/libpyside/signalmanager.cpp +++ b/sources/pyside6/libpyside/signalmanager.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -311,8 +312,21 @@ void SignalManager::setQmlMetaCallErrorHandler(QmlMetaCallErrorHandler handler) SignalManagerPrivate::m_qmlMetaCallErrorHandler = handler; } +static void qAppAboutToQuit() +{ + SignalManager::instance().purgeEmptyGlobalReceivers(); +} + QObject *SignalManager::globalReceiver(QObject *sender, PyObject *callback, QObject *receiver) { + static bool registerQuitHandler = true; + if (registerQuitHandler) { + if (auto *app = QCoreApplication::instance()) { + registerQuitHandler = false; + QObject::connect(app, &QCoreApplication::aboutToQuit, qAppAboutToQuit); + } + } + auto &globalReceivers = m_d->m_globalReceivers; const GlobalReceiverKey key = GlobalReceiverV2::key(callback); auto it = globalReceivers.find(key); @@ -326,10 +340,15 @@ QObject *SignalManager::globalReceiver(QObject *sender, PyObject *callback, QObj return it.value().get(); } +void SignalManager::purgeEmptyGlobalReceivers() +{ + m_d->purgeEmptyGlobalReceivers(); +} + void SignalManager::notifyGlobalReceiver(QObject *receiver) { reinterpret_cast(receiver)->notify(); - m_d->purgeEmptyGlobalReceivers(); + purgeEmptyGlobalReceivers(); } void SignalManager::releaseGlobalReceiver(const QObject *source, QObject *receiver) diff --git a/sources/pyside6/libpyside/signalmanager.h b/sources/pyside6/libpyside/signalmanager.h index 684a4e5e7..c531d6630 100644 --- a/sources/pyside6/libpyside/signalmanager.h +++ b/sources/pyside6/libpyside/signalmanager.h @@ -78,6 +78,7 @@ public: // Disconnect all signals managed by Globalreceiver void clear(); + void purgeEmptyGlobalReceivers(); // Utility function to call a python method usign args received in qt_metacall static int callPythonMetaMethod(const QMetaMethod& method, void** args, PyObject* obj, bool isShortCuit); -- cgit v1.2.3