forked from qt-creator/qt-creator
CppProjectUpdater: Wait for all tasks to be finished in d'tor
It may happen that the old task was canceled and still running
while the new task was started. Later, when the d'tor is called
both old and new tasks may still be running. Before we waited only
for the new task to be finished in d'tor. Now we are waiting
for all tasks to be finished.
Amends: 7fb592fe0c
Task-number: QTCREATORBUG-25709
Change-Id: Id4b44cd36ee03aa45472b15d8fbb25a2cab77e92
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
@@ -43,11 +43,7 @@ CppProjectUpdater::CppProjectUpdater()
|
|||||||
&QFutureWatcher<ProjectInfo>::finished,
|
&QFutureWatcher<ProjectInfo>::finished,
|
||||||
this,
|
this,
|
||||||
&CppProjectUpdater::onProjectInfoGenerated);
|
&CppProjectUpdater::onProjectInfoGenerated);
|
||||||
}
|
m_futureSynchronizer.setCancelOnWait(true);
|
||||||
|
|
||||||
CppProjectUpdater::~CppProjectUpdater()
|
|
||||||
{
|
|
||||||
cancelAndWaitForFinished();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppProjectUpdater::update(const ProjectExplorer::ProjectUpdateInfo &projectUpdateInfo)
|
void CppProjectUpdater::update(const ProjectExplorer::ProjectUpdateInfo &projectUpdateInfo)
|
||||||
@@ -63,30 +59,21 @@ void CppProjectUpdater::update(const ProjectExplorer::ProjectUpdateInfo &project
|
|||||||
this, &CppProjectUpdater::onToolChainRemoved);
|
this, &CppProjectUpdater::onToolChainRemoved);
|
||||||
|
|
||||||
// Run the project info generator in a worker thread and continue if that one is finished.
|
// Run the project info generator in a worker thread and continue if that one is finished.
|
||||||
m_generateFuture = Utils::runAsync([=](QFutureInterface<ProjectInfo> &futureInterface) {
|
auto generateFuture = Utils::runAsync([=](QFutureInterface<ProjectInfo> &futureInterface) {
|
||||||
ProjectUpdateInfo fullProjectUpdateInfo = projectUpdateInfo;
|
ProjectUpdateInfo fullProjectUpdateInfo = projectUpdateInfo;
|
||||||
if (fullProjectUpdateInfo.rppGenerator)
|
if (fullProjectUpdateInfo.rppGenerator)
|
||||||
fullProjectUpdateInfo.rawProjectParts = fullProjectUpdateInfo.rppGenerator();
|
fullProjectUpdateInfo.rawProjectParts = fullProjectUpdateInfo.rppGenerator();
|
||||||
Internal::ProjectInfoGenerator generator(futureInterface, fullProjectUpdateInfo);
|
Internal::ProjectInfoGenerator generator(futureInterface, fullProjectUpdateInfo);
|
||||||
futureInterface.reportResult(generator.generate());
|
futureInterface.reportResult(generator.generate());
|
||||||
});
|
});
|
||||||
m_generateFutureWatcher.setFuture(m_generateFuture);
|
m_generateFutureWatcher.setFuture(generateFuture);
|
||||||
|
m_futureSynchronizer.addFuture(generateFuture);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppProjectUpdater::cancel()
|
void CppProjectUpdater::cancel()
|
||||||
{
|
{
|
||||||
m_generateFutureWatcher.setFuture({});
|
m_generateFutureWatcher.setFuture({});
|
||||||
m_generateFuture.cancel();
|
m_futureSynchronizer.cancelAllFutures();
|
||||||
m_updateFuture.cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CppProjectUpdater::cancelAndWaitForFinished()
|
|
||||||
{
|
|
||||||
cancel();
|
|
||||||
if (m_generateFuture.isRunning())
|
|
||||||
m_generateFuture.waitForFinished();
|
|
||||||
if (m_updateFuture.isRunning())
|
|
||||||
m_updateFuture.waitForFinished();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppProjectUpdater::onToolChainRemoved(ProjectExplorer::ToolChain *t)
|
void CppProjectUpdater::onToolChainRemoved(ProjectExplorer::ToolChain *t)
|
||||||
@@ -106,8 +93,9 @@ void CppProjectUpdater::onProjectInfoGenerated()
|
|||||||
if (m_generateFutureWatcher.isCanceled() || m_generateFutureWatcher.future().resultCount() < 1)
|
if (m_generateFutureWatcher.isCanceled() || m_generateFutureWatcher.future().resultCount() < 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_updateFuture = CppModelManager::instance()->updateProjectInfo(
|
auto updateFuture = CppModelManager::instance()->updateProjectInfo(
|
||||||
m_generateFutureWatcher.result());
|
m_generateFutureWatcher.result());
|
||||||
|
m_futureSynchronizer.addFuture(updateFuture);
|
||||||
}
|
}
|
||||||
|
|
||||||
CppProjectUpdaterFactory::CppProjectUpdaterFactory()
|
CppProjectUpdaterFactory::CppProjectUpdaterFactory()
|
||||||
|
@@ -29,6 +29,8 @@
|
|||||||
#include "cpptools_global.h"
|
#include "cpptools_global.h"
|
||||||
#include "projectinfo.h"
|
#include "projectinfo.h"
|
||||||
|
|
||||||
|
#include <utils/futuresynchronizer.h>
|
||||||
|
|
||||||
#include <QFutureWatcher>
|
#include <QFutureWatcher>
|
||||||
|
|
||||||
namespace CppTools {
|
namespace CppTools {
|
||||||
@@ -52,23 +54,19 @@ class CPPTOOLS_EXPORT CppProjectUpdater final : public QObject, public CppProjec
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
CppProjectUpdater();
|
CppProjectUpdater();
|
||||||
~CppProjectUpdater() override;
|
|
||||||
|
|
||||||
void update(const ProjectExplorer::ProjectUpdateInfo &projectUpdateInfo) override;
|
void update(const ProjectExplorer::ProjectUpdateInfo &projectUpdateInfo) override;
|
||||||
void cancel() override;
|
void cancel() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void cancelAndWaitForFinished();
|
|
||||||
|
|
||||||
void onToolChainRemoved(ProjectExplorer::ToolChain *);
|
void onToolChainRemoved(ProjectExplorer::ToolChain *);
|
||||||
void onProjectInfoGenerated();
|
void onProjectInfoGenerated();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ProjectExplorer::ProjectUpdateInfo m_projectUpdateInfo;
|
ProjectExplorer::ProjectUpdateInfo m_projectUpdateInfo;
|
||||||
|
|
||||||
QFuture<ProjectInfo> m_generateFuture;
|
|
||||||
QFuture<void> m_updateFuture;
|
|
||||||
QFutureWatcher<ProjectInfo> m_generateFutureWatcher;
|
QFutureWatcher<ProjectInfo> m_generateFutureWatcher;
|
||||||
|
Utils::FutureSynchronizer m_futureSynchronizer;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace CppTools
|
} // namespace CppTools
|
||||||
|
Reference in New Issue
Block a user