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;
|
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,11 +404,12 @@ 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());
|
||||||
@@ -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,
|
||||||
|
@@ -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);
|
||||||
|
Reference in New Issue
Block a user