ProgressManager: Avoid deleting object from its signal handler

Don't delete future watcher object directly from inside
taskFinished(), as this method is the direct watcher's
signal handler.

Avoid using sender() - use lambda instead.

Disconnect from all watcher's signals (instead of selected)
prior to delete.

Change-Id: Ib4b5a7341bef9979bda9c047ab98787974d1bc12
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
Jarek Kobus
2022-07-19 16:59:41 +02:00
parent 697df89178
commit 62b1d574f5
2 changed files with 14 additions and 12 deletions

View File

@@ -340,9 +340,9 @@ void ProgressManagerPrivate::doCancelTasks(Id type)
continue; continue;
} }
found = true; found = true;
disconnect(task.key(), &QFutureWatcherBase::finished, this, &ProgressManagerPrivate::taskFinished);
if (m_applicationTask == task.key()) if (m_applicationTask == task.key())
disconnectApplicationTask(); disconnectApplicationTask();
task.key()->disconnect();
task.key()->cancel(); task.key()->cancel();
delete task.key(); delete task.key();
task = m_runningTasks.erase(task); task = m_runningTasks.erase(task);
@@ -383,9 +383,9 @@ void ProgressManagerPrivate::cancelAllRunningTasks()
{ {
QMap<QFutureWatcher<void> *, Id>::const_iterator task = m_runningTasks.constBegin(); QMap<QFutureWatcher<void> *, Id>::const_iterator task = m_runningTasks.constBegin();
while (task != m_runningTasks.constEnd()) { while (task != m_runningTasks.constEnd()) {
disconnect(task.key(), &QFutureWatcherBase::finished, this, &ProgressManagerPrivate::taskFinished);
if (m_applicationTask == task.key()) if (m_applicationTask == task.key())
disconnectApplicationTask(); disconnectApplicationTask();
task.key()->disconnect();
task.key()->cancel(); task.key()->cancel();
delete task.key(); delete task.key();
++task; ++task;
@@ -404,12 +404,13 @@ FutureProgress *ProgressManagerPrivate::doAddTask(const QFuture<void> &future, c
this, &ProgressManagerPrivate::updateSummaryProgressBar); this, &ProgressManagerPrivate::updateSummaryProgressBar);
connect(watcher, &QFutureWatcherBase::progressValueChanged, connect(watcher, &QFutureWatcherBase::progressValueChanged,
this, &ProgressManagerPrivate::updateSummaryProgressBar); this, &ProgressManagerPrivate::updateSummaryProgressBar);
connect(watcher, &QFutureWatcherBase::finished, this, &ProgressManagerPrivate::taskFinished); connect(watcher, &QFutureWatcherBase::finished, this, [this, watcher] {
taskFinished(watcher);
});
// handle application task // handle application task
if (flags & ShowInApplicationIcon) { if (flags & ShowInApplicationIcon) {
if (m_applicationTask) disconnectApplicationTask();
disconnectApplicationTask();
m_applicationTask = watcher; m_applicationTask = watcher;
setApplicationProgressRange(future.progressMinimum(), future.progressMaximum()); setApplicationProgressRange(future.progressMinimum(), future.progressMaximum());
setApplicationProgressValue(future.progressValue()); setApplicationProgressValue(future.progressValue());
@@ -461,16 +462,14 @@ ProgressView *ProgressManagerPrivate::progressView()
return m_progressView; return m_progressView;
} }
void ProgressManagerPrivate::taskFinished() void ProgressManagerPrivate::taskFinished(QFutureWatcher<void> *task)
{ {
QObject *taskObject = sender(); const Id type = m_runningTasks.value(task);
QTC_ASSERT(taskObject, return);
auto task = static_cast<QFutureWatcher<void> *>(taskObject);
if (m_applicationTask == task) if (m_applicationTask == task)
disconnectApplicationTask(); disconnectApplicationTask();
Id type = m_runningTasks.value(task); task->disconnect();
task->deleteLater();
m_runningTasks.remove(task); m_runningTasks.remove(task);
delete task;
updateSummaryProgressBar(); updateSummaryProgressBar();
if (!m_runningTasks.key(type, 0)) if (!m_runningTasks.key(type, 0))
@@ -479,6 +478,9 @@ void ProgressManagerPrivate::taskFinished()
void ProgressManagerPrivate::disconnectApplicationTask() void ProgressManagerPrivate::disconnectApplicationTask()
{ {
if (!m_applicationTask)
return;
disconnect(m_applicationTask, &QFutureWatcherBase::progressRangeChanged, disconnect(m_applicationTask, &QFutureWatcherBase::progressRangeChanged,
this, &ProgressManagerPrivate::setApplicationProgressRange); this, &ProgressManagerPrivate::setApplicationProgressRange);
disconnect(m_applicationTask, &QFutureWatcherBase::progressValueChanged, disconnect(m_applicationTask, &QFutureWatcherBase::progressValueChanged,

View File

@@ -67,7 +67,7 @@ protected:
bool eventFilter(QObject *obj, QEvent *event) override; bool eventFilter(QObject *obj, QEvent *event) override;
private: private:
void taskFinished(); void taskFinished(QFutureWatcher<void> *task);
void cancelAllRunningTasks(); void cancelAllRunningTasks();
void setApplicationProgressRange(int min, int max); void setApplicationProgressRange(int min, int max);
void setApplicationProgressValue(int value); void setApplicationProgressValue(int value);