From 6517d72d1349c974b61217e81b5f1e17e5a93430 Mon Sep 17 00:00:00 2001 From: Pierre Lamot <pierre@videolabs.io> Date: Thu, 6 Jan 2022 18:21:42 +0100 Subject: [PATCH] qt: don't handle object destruction event after ML task is done or canceled The MediaLib object can perform ML requests itself, this would register an event called on object destruction, that would callback on itself but the MediaLib would be in an invalid state (partially destroyed). Anyway we shouldn't handle object destruction events after ML task is done or canceled fix: #26448 --- modules/gui/qt/medialibrary/medialib.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/modules/gui/qt/medialibrary/medialib.cpp b/modules/gui/qt/medialibrary/medialib.cpp index ef4cbdf52621..ad51ecea8e6e 100644 --- a/modules/gui/qt/medialibrary/medialib.cpp +++ b/modules/gui/qt/medialibrary/medialib.cpp @@ -42,6 +42,8 @@ MediaLib::MediaLib(qt_intf_t *_intf, QObject *_parent) MediaLib::~MediaLib() { + assert(m_objectTasks.empty()); + assert(m_runningTasks.empty()); } void MediaLib::destroy() @@ -50,6 +52,7 @@ void MediaLib::destroy() //try to cancel as many tasks as possible for (auto taskIt = m_objectTasks.begin(); taskIt != m_objectTasks.end(); /**/) { + const QObject* object = taskIt.key(); quint64 key = taskIt.value(); auto task = m_runningTasks.value(key, nullptr); if (m_mlThreadPool.tryTake(task)) @@ -57,6 +60,8 @@ void MediaLib::destroy() delete task; m_runningTasks.remove(key); taskIt = m_objectTasks.erase(taskIt); + if (m_objectTasks.count(object) == 0) + disconnect(object, &QObject::destroyed, this, &MediaLib::runOnMLThreadTargetDestroyed); } else ++taskIt; @@ -468,6 +473,8 @@ void MediaLib::cancelMLTask(const QObject* object, quint64 taskId) delete task; m_runningTasks.remove(taskId); m_objectTasks.remove(object, taskId); + if (m_objectTasks.count(object) == 0) + disconnect(object, &QObject::destroyed, this, &MediaLib::runOnMLThreadTargetDestroyed); } void MediaLib::runOnMLThreadDone(RunOnMLThreadBaseRunner* runner, quint64 target, const QObject* object, int status) @@ -478,6 +485,8 @@ void MediaLib::runOnMLThreadDone(RunOnMLThreadBaseRunner* runner, quint64 target { m_runningTasks.remove(target); m_objectTasks.remove(object, target); + if (m_objectTasks.count(object) == 0) + disconnect(object, &QObject::destroyed, this, &MediaLib::runOnMLThreadTargetDestroyed); } if (m_runningTasks.empty()) deleteLater(); @@ -488,6 +497,8 @@ void MediaLib::runOnMLThreadDone(RunOnMLThreadBaseRunner* runner, quint64 target runner->runUICallback(); m_runningTasks.remove(target); m_objectTasks.remove(object, target); + if (m_objectTasks.count(object) == 0) + disconnect(object, &QObject::destroyed, this, &MediaLib::runOnMLThreadTargetDestroyed); } runner->deleteLater(); } @@ -506,5 +517,6 @@ void MediaLib::runOnMLThreadTargetDestroyed(QObject * object) m_runningTasks.remove(taskId); } m_objectTasks.remove(object); + //no need to disconnect QObject::destroyed, as object is currently being destroyed } } -- GitLab