ProgressManager: Handle QFutureInterface by value in addTimedTask

QFutureInterface acts by a shared pointer itself, so use that to
guards against the QFutureInterface object being destroyed while
the timer is running.

This feels awkward as QFutureInterfaceBase::future() is non-const
for unknown reason.

Change-Id: I1d43abe0c27183af2f01cf269e2a94d2fcaba46e
Reviewed-by: Eike Ziller <eike.ziller@digia.com>
This commit is contained in:
hjk
2014-05-30 14:25:58 +02:00
parent 212836d56b
commit 54cac66c72
5 changed files with 17 additions and 18 deletions

View File

@@ -749,10 +749,11 @@ FutureProgress *ProgressManager::addTask(const QFuture<void> &future, const QStr
\sa addTask \sa addTask
*/ */
FutureProgress *ProgressManager::addTimedTask(QFutureInterface<void> *futureInterface, const QString &title, FutureProgress *ProgressManager::addTimedTask(const QFutureInterface<void> &futureInterface, const QString &title,
Id type, int expectedSeconds, ProgressFlags flags) Id type, int expectedSeconds, ProgressFlags flags)
{ {
FutureProgress *fp = m_instance->doAddTask(futureInterface->future(), title, type, flags); QFutureInterface<void> dummy(futureInterface); // Need mutable to access .future()
FutureProgress *fp = m_instance->doAddTask(dummy.future(), title, type, flags);
(void) new ProgressTimer(fp, futureInterface, expectedSeconds); (void) new ProgressTimer(fp, futureInterface, expectedSeconds);
return fp; return fp;
} }
@@ -770,17 +771,17 @@ void ProgressManager::cancelTasks(const Id type)
ProgressTimer::ProgressTimer(QObject *parent, ProgressTimer::ProgressTimer(QObject *parent,
QFutureInterface<void> *futureInterface, const QFutureInterface<void> &futureInterface,
int expectedSeconds) int expectedSeconds)
: QTimer(parent), : QTimer(parent),
m_futureInterface(futureInterface), m_futureInterface(futureInterface),
m_expectedTime(expectedSeconds), m_expectedTime(expectedSeconds),
m_currentTime(0) m_currentTime(0)
{ {
m_futureWatcher.setFuture(futureInterface->future()); m_futureWatcher.setFuture(m_futureInterface.future());
m_futureInterface->setProgressRange(0, 100); m_futureInterface.setProgressRange(0, 100);
m_futureInterface->setProgressValue(0); m_futureInterface.setProgressValue(0);
setInterval(1000); // 1 second setInterval(1000); // 1 second
connect(this, SIGNAL(timeout()), this, SLOT(handleTimeout())); connect(this, SIGNAL(timeout()), this, SLOT(handleTimeout()));
@@ -796,6 +797,6 @@ void ProgressTimer::handleTimeout()
// future finishes. That's not bad for a random choice. // future finishes. That's not bad for a random choice.
const double mapped = atan2(double(m_currentTime), double(m_expectedTime)); const double mapped = atan2(double(m_currentTime), double(m_expectedTime));
const double progress = 100 * 2 * mapped / 3.14; const double progress = 100 * 2 * mapped / 3.14;
m_futureInterface->setProgressValue(int(progress)); m_futureInterface.setProgressValue(int(progress));
} }

View File

@@ -55,7 +55,7 @@ public:
static FutureProgress *addTask(const QFuture<void> &future, const QString &title, static FutureProgress *addTask(const QFuture<void> &future, const QString &title,
Core::Id type, ProgressFlags flags = 0); Core::Id type, ProgressFlags flags = 0);
static FutureProgress *addTimedTask(QFutureInterface<void> *fi, const QString &title, static FutureProgress *addTimedTask(const QFutureInterface<void> &fi, const QString &title,
Core::Id type, int expectedSeconds, ProgressFlags flags = 0); Core::Id type, int expectedSeconds, ProgressFlags flags = 0);
static void setApplicationLabel(const QString &text); static void setApplicationLabel(const QString &text);

View File

@@ -132,13 +132,13 @@ class ProgressTimer : public QTimer
Q_OBJECT Q_OBJECT
public: public:
ProgressTimer(QObject *parent, QFutureInterface<void> *futureInterface, int expectedSeconds); ProgressTimer(QObject *parent, const QFutureInterface<void> &futureInterface, int expectedSeconds);
private slots: private slots:
void handleTimeout(); void handleTimeout();
private: private:
QFutureInterface<void> *m_futureInterface; QFutureInterface<void> m_futureInterface;
QFutureWatcher<void> m_futureWatcher; QFutureWatcher<void> m_futureWatcher;
int m_expectedTime; int m_expectedTime;
int m_currentTime; int m_currentTime;

View File

@@ -57,7 +57,6 @@ ValgrindRunControl::ValgrindRunControl(const AnalyzerStartParameters &sp,
ProjectExplorer::RunConfiguration *runConfiguration) ProjectExplorer::RunConfiguration *runConfiguration)
: AnalyzerRunControl(sp, runConfiguration), : AnalyzerRunControl(sp, runConfiguration),
m_settings(0), m_settings(0),
m_progress(new QFutureInterface<void>()),
m_isStopping(false) m_isStopping(false)
{ {
if (runConfiguration) if (runConfiguration)
@@ -71,7 +70,6 @@ ValgrindRunControl::ValgrindRunControl(const AnalyzerStartParameters &sp,
ValgrindRunControl::~ValgrindRunControl() ValgrindRunControl::~ValgrindRunControl()
{ {
delete m_progress;
} }
bool ValgrindRunControl::startEngine() bool ValgrindRunControl::startEngine()
@@ -82,7 +80,7 @@ bool ValgrindRunControl::startEngine()
fp->setKeepOnFinish(FutureProgress::HideOnFinish); fp->setKeepOnFinish(FutureProgress::HideOnFinish);
connect(fp, SIGNAL(canceled()), this, SLOT(handleProgressCanceled())); connect(fp, SIGNAL(canceled()), this, SLOT(handleProgressCanceled()));
connect(fp, SIGNAL(finished()), this, SLOT(handleProgressFinished())); connect(fp, SIGNAL(finished()), this, SLOT(handleProgressFinished()));
m_progress->reportStarted(); m_progress.reportStarted();
const AnalyzerStartParameters &sp = startParameters(); const AnalyzerStartParameters &sp = startParameters();
#if VALGRIND_DEBUG_OUTPUT #if VALGRIND_DEBUG_OUTPUT
@@ -112,7 +110,7 @@ bool ValgrindRunControl::startEngine()
connect(run, SIGNAL(finished()), SLOT(runnerFinished())); connect(run, SIGNAL(finished()), SLOT(runnerFinished()));
if (!run->start()) { if (!run->start()) {
m_progress->cancel(); m_progress.cancel();
return false; return false;
} }
return true; return true;
@@ -154,8 +152,8 @@ QStringList ValgrindRunControl::genericToolArguments() const
void ValgrindRunControl::handleProgressCanceled() void ValgrindRunControl::handleProgressCanceled()
{ {
AnalyzerManager::stopTool(); AnalyzerManager::stopTool();
m_progress->reportCanceled(); m_progress.reportCanceled();
m_progress->reportFinished(); m_progress.reportFinished();
} }
void ValgrindRunControl::handleProgressFinished() void ValgrindRunControl::handleProgressFinished()
@@ -168,7 +166,7 @@ void ValgrindRunControl::runnerFinished()
appendMessage(tr("Analyzing finished.") + QLatin1Char('\n'), NormalMessageFormat); appendMessage(tr("Analyzing finished.") + QLatin1Char('\n'), NormalMessageFormat);
emit finished(); emit finished();
m_progress->reportFinished(); m_progress.reportFinished();
disconnect(runner(), SIGNAL(processOutputReceived(QString,Utils::OutputFormat)), disconnect(runner(), SIGNAL(processOutputReceived(QString,Utils::OutputFormat)),
this, SLOT(receiveProcessOutput(QString,Utils::OutputFormat))); this, SLOT(receiveProcessOutput(QString,Utils::OutputFormat)));

View File

@@ -62,7 +62,7 @@ protected:
virtual Valgrind::ValgrindRunner *runner() = 0; virtual Valgrind::ValgrindRunner *runner() = 0;
ValgrindBaseSettings *m_settings; ValgrindBaseSettings *m_settings;
QFutureInterface<void> *m_progress; QFutureInterface<void> m_progress;
private slots: private slots:
void handleProgressCanceled(); void handleProgressCanceled();