forked from qt-creator/qt-creator
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:
@@ -340,9 +340,9 @@ void ProgressManagerPrivate::doCancelTasks(Id type)
|
||||
continue;
|
||||
}
|
||||
found = true;
|
||||
disconnect(task.key(), &QFutureWatcherBase::finished, this, &ProgressManagerPrivate::taskFinished);
|
||||
if (m_applicationTask == task.key())
|
||||
disconnectApplicationTask();
|
||||
task.key()->disconnect();
|
||||
task.key()->cancel();
|
||||
delete task.key();
|
||||
task = m_runningTasks.erase(task);
|
||||
@@ -383,9 +383,9 @@ void ProgressManagerPrivate::cancelAllRunningTasks()
|
||||
{
|
||||
QMap<QFutureWatcher<void> *, Id>::const_iterator task = m_runningTasks.constBegin();
|
||||
while (task != m_runningTasks.constEnd()) {
|
||||
disconnect(task.key(), &QFutureWatcherBase::finished, this, &ProgressManagerPrivate::taskFinished);
|
||||
if (m_applicationTask == task.key())
|
||||
disconnectApplicationTask();
|
||||
task.key()->disconnect();
|
||||
task.key()->cancel();
|
||||
delete task.key();
|
||||
++task;
|
||||
@@ -404,11 +404,12 @@ FutureProgress *ProgressManagerPrivate::doAddTask(const QFuture<void> &future, c
|
||||
this, &ProgressManagerPrivate::updateSummaryProgressBar);
|
||||
connect(watcher, &QFutureWatcherBase::progressValueChanged,
|
||||
this, &ProgressManagerPrivate::updateSummaryProgressBar);
|
||||
connect(watcher, &QFutureWatcherBase::finished, this, &ProgressManagerPrivate::taskFinished);
|
||||
connect(watcher, &QFutureWatcherBase::finished, this, [this, watcher] {
|
||||
taskFinished(watcher);
|
||||
});
|
||||
|
||||
// handle application task
|
||||
if (flags & ShowInApplicationIcon) {
|
||||
if (m_applicationTask)
|
||||
disconnectApplicationTask();
|
||||
m_applicationTask = watcher;
|
||||
setApplicationProgressRange(future.progressMinimum(), future.progressMaximum());
|
||||
@@ -461,16 +462,14 @@ ProgressView *ProgressManagerPrivate::progressView()
|
||||
return m_progressView;
|
||||
}
|
||||
|
||||
void ProgressManagerPrivate::taskFinished()
|
||||
void ProgressManagerPrivate::taskFinished(QFutureWatcher<void> *task)
|
||||
{
|
||||
QObject *taskObject = sender();
|
||||
QTC_ASSERT(taskObject, return);
|
||||
auto task = static_cast<QFutureWatcher<void> *>(taskObject);
|
||||
const Id type = m_runningTasks.value(task);
|
||||
if (m_applicationTask == task)
|
||||
disconnectApplicationTask();
|
||||
Id type = m_runningTasks.value(task);
|
||||
task->disconnect();
|
||||
task->deleteLater();
|
||||
m_runningTasks.remove(task);
|
||||
delete task;
|
||||
updateSummaryProgressBar();
|
||||
|
||||
if (!m_runningTasks.key(type, 0))
|
||||
@@ -479,6 +478,9 @@ void ProgressManagerPrivate::taskFinished()
|
||||
|
||||
void ProgressManagerPrivate::disconnectApplicationTask()
|
||||
{
|
||||
if (!m_applicationTask)
|
||||
return;
|
||||
|
||||
disconnect(m_applicationTask, &QFutureWatcherBase::progressRangeChanged,
|
||||
this, &ProgressManagerPrivate::setApplicationProgressRange);
|
||||
disconnect(m_applicationTask, &QFutureWatcherBase::progressValueChanged,
|
||||
|
@@ -67,7 +67,7 @@ protected:
|
||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||
|
||||
private:
|
||||
void taskFinished();
|
||||
void taskFinished(QFutureWatcher<void> *task);
|
||||
void cancelAllRunningTasks();
|
||||
void setApplicationProgressRange(int min, int max);
|
||||
void setApplicationProgressValue(int value);
|
||||
|
Reference in New Issue
Block a user