ProjectExplorer: Gracefully abort process upon ExtraCompiler delete

Task-number: QTCREATORBUG-15993
Change-Id: I9d3bf92a6c2e41bb40a01a1a613f6b98f72cf6be
Reviewed-by: Ulf Hermann <ulf.hermann@theqtcompany.com>
Reviewed-by: Tobias Hunger <tobias.hunger@theqtcompany.com>
This commit is contained in:
Orgad Shaneh
2016-04-03 11:54:31 +03:00
committed by Orgad Shaneh
parent f589e8b38d
commit e883650ed5
2 changed files with 36 additions and 12 deletions

View File

@@ -375,6 +375,14 @@ ProcessExtraCompiler::ProcessExtraCompiler(const Project *project, const Utils::
ExtraCompiler(project, source, targets, parent) ExtraCompiler(project, source, targets, parent)
{ } { }
ProcessExtraCompiler::~ProcessExtraCompiler()
{
if (!m_watcher)
return;
m_watcher->cancel();
m_watcher->waitForFinished();
}
void ProcessExtraCompiler::run(const QByteArray &sourceContents) void ProcessExtraCompiler::run(const QByteArray &sourceContents)
{ {
ContentProvider contents = [this, sourceContents]() { return sourceContents; }; ContentProvider contents = [this, sourceContents]() { return sourceContents; };
@@ -429,17 +437,18 @@ void ProcessExtraCompiler::runImpl(const ContentProvider &provider)
buildEnvironment())); buildEnvironment()));
} }
FileNameToContentsHash ProcessExtraCompiler::runInThread( void ProcessExtraCompiler::runInThread(
QFutureInterface<FileNameToContentsHash> &futureInterface,
const Utils::FileName &cmd, const Utils::FileName &workDir, const Utils::FileName &cmd, const Utils::FileName &workDir,
const QStringList &args, const ContentProvider &provider, const QStringList &args, const ContentProvider &provider,
const Utils::Environment &env) const Utils::Environment &env)
{ {
if (cmd.isEmpty() || !cmd.toFileInfo().isExecutable()) if (cmd.isEmpty() || !cmd.toFileInfo().isExecutable())
return FileNameToContentsHash(); return;
const QByteArray sourceContents = provider(); const QByteArray sourceContents = provider();
if (sourceContents.isNull() || !prepareToRun(sourceContents)) if (sourceContents.isNull() || !prepareToRun(sourceContents))
return FileNameToContentsHash(); return;
QProcess process; QProcess process;
@@ -449,25 +458,38 @@ FileNameToContentsHash ProcessExtraCompiler::runInThread(
process.start(cmd.toString(), args, QIODevice::ReadWrite); process.start(cmd.toString(), args, QIODevice::ReadWrite);
if (!process.waitForStarted()) { if (!process.waitForStarted()) {
handleProcessError(&process); handleProcessError(&process);
return FileNameToContentsHash(); return;
} }
bool isCanceled = futureInterface.isCanceled();
if (!isCanceled) {
handleProcessStarted(&process, sourceContents); handleProcessStarted(&process, sourceContents);
process.waitForFinished(); forever {
bool done = process.waitForFinished(200);
isCanceled = futureInterface.isCanceled();
if (done || isCanceled)
break;
}
}
if (process.state() == QProcess::Running) { isCanceled |= process.state() == QProcess::Running;
if (isCanceled) {
process.kill(); process.kill();
process.waitForFinished(3000); process.waitForFinished(3000);
return;
} }
return handleProcessFinished(&process); futureInterface.reportResult(handleProcessFinished(&process));
} }
void ProcessExtraCompiler::cleanUp() void ProcessExtraCompiler::cleanUp()
{ {
QTC_ASSERT(m_watcher, return); QTC_ASSERT(m_watcher, return);
const FileNameToContentsHash data = m_watcher->future().result(); auto future = m_watcher->future();
delete m_watcher; delete m_watcher;
m_watcher = nullptr; m_watcher = nullptr;
if (!future.resultCount())
return;
const FileNameToContentsHash data = future.result();
if (data.isEmpty()) if (data.isEmpty())
return; // There was some kind of error... return; // There was some kind of error...

View File

@@ -101,6 +101,7 @@ public:
ProcessExtraCompiler(const Project *project, const Utils::FileName &source, ProcessExtraCompiler(const Project *project, const Utils::FileName &source,
const Utils::FileNameList &targets, QObject *parent = nullptr); const Utils::FileNameList &targets, QObject *parent = nullptr);
~ProcessExtraCompiler();
protected: protected:
// This will run a process in a thread, if // This will run a process in a thread, if
@@ -128,7 +129,8 @@ protected:
private: private:
using ContentProvider = std::function<QByteArray()>; using ContentProvider = std::function<QByteArray()>;
void runImpl(const ContentProvider &sourceContents); void runImpl(const ContentProvider &sourceContents);
FileNameToContentsHash runInThread(const Utils::FileName &cmd, const Utils::FileName &workDir, void runInThread(QFutureInterface<FileNameToContentsHash> &futureInterface,
const Utils::FileName &cmd, const Utils::FileName &workDir,
const QStringList &args, const ContentProvider &provider, const QStringList &args, const ContentProvider &provider,
const Utils::Environment &env); const Utils::Environment &env);
void cleanUp(); void cleanUp();