forked from qt-creator/qt-creator
		
	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:
		@@ -749,10 +749,11 @@ FutureProgress *ProgressManager::addTask(const QFuture<void> &future, const QStr
 | 
			
		||||
    \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)
 | 
			
		||||
{
 | 
			
		||||
    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);
 | 
			
		||||
    return fp;
 | 
			
		||||
}
 | 
			
		||||
@@ -770,17 +771,17 @@ void ProgressManager::cancelTasks(const Id type)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ProgressTimer::ProgressTimer(QObject *parent,
 | 
			
		||||
                             QFutureInterface<void> *futureInterface,
 | 
			
		||||
                             const QFutureInterface<void> &futureInterface,
 | 
			
		||||
                             int expectedSeconds)
 | 
			
		||||
    : QTimer(parent),
 | 
			
		||||
      m_futureInterface(futureInterface),
 | 
			
		||||
      m_expectedTime(expectedSeconds),
 | 
			
		||||
      m_currentTime(0)
 | 
			
		||||
{
 | 
			
		||||
    m_futureWatcher.setFuture(futureInterface->future());
 | 
			
		||||
    m_futureWatcher.setFuture(m_futureInterface.future());
 | 
			
		||||
 | 
			
		||||
    m_futureInterface->setProgressRange(0, 100);
 | 
			
		||||
    m_futureInterface->setProgressValue(0);
 | 
			
		||||
    m_futureInterface.setProgressRange(0, 100);
 | 
			
		||||
    m_futureInterface.setProgressValue(0);
 | 
			
		||||
 | 
			
		||||
    setInterval(1000); // 1 second
 | 
			
		||||
    connect(this, SIGNAL(timeout()), this, SLOT(handleTimeout()));
 | 
			
		||||
@@ -796,6 +797,6 @@ void ProgressTimer::handleTimeout()
 | 
			
		||||
    // future finishes. That's not bad for a random choice.
 | 
			
		||||
    const double mapped = atan2(double(m_currentTime), double(m_expectedTime));
 | 
			
		||||
    const double progress = 100 * 2 * mapped / 3.14;
 | 
			
		||||
    m_futureInterface->setProgressValue(int(progress));
 | 
			
		||||
    m_futureInterface.setProgressValue(int(progress));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -55,7 +55,7 @@ public:
 | 
			
		||||
 | 
			
		||||
    static FutureProgress *addTask(const QFuture<void> &future, const QString &title,
 | 
			
		||||
                                   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);
 | 
			
		||||
    static void setApplicationLabel(const QString &text);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -132,13 +132,13 @@ class ProgressTimer : public QTimer
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    ProgressTimer(QObject *parent, QFutureInterface<void> *futureInterface, int expectedSeconds);
 | 
			
		||||
    ProgressTimer(QObject *parent, const QFutureInterface<void> &futureInterface, int expectedSeconds);
 | 
			
		||||
 | 
			
		||||
private slots:
 | 
			
		||||
    void handleTimeout();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    QFutureInterface<void> *m_futureInterface;
 | 
			
		||||
    QFutureInterface<void> m_futureInterface;
 | 
			
		||||
    QFutureWatcher<void> m_futureWatcher;
 | 
			
		||||
    int m_expectedTime;
 | 
			
		||||
    int m_currentTime;
 | 
			
		||||
 
 | 
			
		||||
@@ -57,7 +57,6 @@ ValgrindRunControl::ValgrindRunControl(const AnalyzerStartParameters &sp,
 | 
			
		||||
        ProjectExplorer::RunConfiguration *runConfiguration)
 | 
			
		||||
    : AnalyzerRunControl(sp, runConfiguration),
 | 
			
		||||
      m_settings(0),
 | 
			
		||||
      m_progress(new QFutureInterface<void>()),
 | 
			
		||||
      m_isStopping(false)
 | 
			
		||||
{
 | 
			
		||||
    if (runConfiguration)
 | 
			
		||||
@@ -71,7 +70,6 @@ ValgrindRunControl::ValgrindRunControl(const AnalyzerStartParameters &sp,
 | 
			
		||||
 | 
			
		||||
ValgrindRunControl::~ValgrindRunControl()
 | 
			
		||||
{
 | 
			
		||||
    delete m_progress;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool ValgrindRunControl::startEngine()
 | 
			
		||||
@@ -82,7 +80,7 @@ bool ValgrindRunControl::startEngine()
 | 
			
		||||
    fp->setKeepOnFinish(FutureProgress::HideOnFinish);
 | 
			
		||||
    connect(fp, SIGNAL(canceled()), this, SLOT(handleProgressCanceled()));
 | 
			
		||||
    connect(fp, SIGNAL(finished()), this, SLOT(handleProgressFinished()));
 | 
			
		||||
    m_progress->reportStarted();
 | 
			
		||||
    m_progress.reportStarted();
 | 
			
		||||
 | 
			
		||||
    const AnalyzerStartParameters &sp = startParameters();
 | 
			
		||||
#if VALGRIND_DEBUG_OUTPUT
 | 
			
		||||
@@ -112,7 +110,7 @@ bool ValgrindRunControl::startEngine()
 | 
			
		||||
    connect(run, SIGNAL(finished()), SLOT(runnerFinished()));
 | 
			
		||||
 | 
			
		||||
    if (!run->start()) {
 | 
			
		||||
        m_progress->cancel();
 | 
			
		||||
        m_progress.cancel();
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
@@ -154,8 +152,8 @@ QStringList ValgrindRunControl::genericToolArguments() const
 | 
			
		||||
void ValgrindRunControl::handleProgressCanceled()
 | 
			
		||||
{
 | 
			
		||||
    AnalyzerManager::stopTool();
 | 
			
		||||
    m_progress->reportCanceled();
 | 
			
		||||
    m_progress->reportFinished();
 | 
			
		||||
    m_progress.reportCanceled();
 | 
			
		||||
    m_progress.reportFinished();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ValgrindRunControl::handleProgressFinished()
 | 
			
		||||
@@ -168,7 +166,7 @@ void ValgrindRunControl::runnerFinished()
 | 
			
		||||
    appendMessage(tr("Analyzing finished.") + QLatin1Char('\n'), NormalMessageFormat);
 | 
			
		||||
    emit finished();
 | 
			
		||||
 | 
			
		||||
    m_progress->reportFinished();
 | 
			
		||||
    m_progress.reportFinished();
 | 
			
		||||
 | 
			
		||||
    disconnect(runner(), SIGNAL(processOutputReceived(QString,Utils::OutputFormat)),
 | 
			
		||||
               this, SLOT(receiveProcessOutput(QString,Utils::OutputFormat)));
 | 
			
		||||
 
 | 
			
		||||
@@ -62,7 +62,7 @@ protected:
 | 
			
		||||
    virtual Valgrind::ValgrindRunner *runner() = 0;
 | 
			
		||||
 | 
			
		||||
    ValgrindBaseSettings *m_settings;
 | 
			
		||||
    QFutureInterface<void> *m_progress;
 | 
			
		||||
    QFutureInterface<void> m_progress;
 | 
			
		||||
 | 
			
		||||
private slots:
 | 
			
		||||
    void handleProgressCanceled();
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user