Commit e883650e authored by Orgad Shaneh's avatar Orgad Shaneh Committed by Orgad Shaneh

ProjectExplorer: Gracefully abort process upon ExtraCompiler delete

Task-number: QTCREATORBUG-15993
Change-Id: I9d3bf92a6c2e41bb40a01a1a613f6b98f72cf6be
Reviewed-by: default avatarUlf Hermann <ulf.hermann@theqtcompany.com>
Reviewed-by: default avatarTobias Hunger <tobias.hunger@theqtcompany.com>
parent f589e8b3
......@@ -375,6 +375,14 @@ ProcessExtraCompiler::ProcessExtraCompiler(const Project *project, const Utils::
ExtraCompiler(project, source, targets, parent)
{ }
ProcessExtraCompiler::~ProcessExtraCompiler()
{
if (!m_watcher)
return;
m_watcher->cancel();
m_watcher->waitForFinished();
}
void ProcessExtraCompiler::run(const QByteArray &sourceContents)
{
ContentProvider contents = [this, sourceContents]() { return sourceContents; };
......@@ -429,17 +437,18 @@ void ProcessExtraCompiler::runImpl(const ContentProvider &provider)
buildEnvironment()));
}
FileNameToContentsHash ProcessExtraCompiler::runInThread(
void ProcessExtraCompiler::runInThread(
QFutureInterface<FileNameToContentsHash> &futureInterface,
const Utils::FileName &cmd, const Utils::FileName &workDir,
const QStringList &args, const ContentProvider &provider,
const Utils::Environment &env)
{
if (cmd.isEmpty() || !cmd.toFileInfo().isExecutable())
return FileNameToContentsHash();
return;
const QByteArray sourceContents = provider();
if (sourceContents.isNull() || !prepareToRun(sourceContents))
return FileNameToContentsHash();
return;
QProcess process;
......@@ -449,25 +458,38 @@ FileNameToContentsHash ProcessExtraCompiler::runInThread(
process.start(cmd.toString(), args, QIODevice::ReadWrite);
if (!process.waitForStarted()) {
handleProcessError(&process);
return FileNameToContentsHash();
return;
}
bool isCanceled = futureInterface.isCanceled();
if (!isCanceled) {
handleProcessStarted(&process, sourceContents);
forever {
bool done = process.waitForFinished(200);
isCanceled = futureInterface.isCanceled();
if (done || isCanceled)
break;
}
}
handleProcessStarted(&process, sourceContents);
process.waitForFinished();
if (process.state() == QProcess::Running) {
isCanceled |= process.state() == QProcess::Running;
if (isCanceled) {
process.kill();
process.waitForFinished(3000);
return;
}
return handleProcessFinished(&process);
futureInterface.reportResult(handleProcessFinished(&process));
}
void ProcessExtraCompiler::cleanUp()
{
QTC_ASSERT(m_watcher, return);
const FileNameToContentsHash data = m_watcher->future().result();
auto future = m_watcher->future();
delete m_watcher;
m_watcher = nullptr;
if (!future.resultCount())
return;
const FileNameToContentsHash data = future.result();
if (data.isEmpty())
return; // There was some kind of error...
......
......@@ -101,6 +101,7 @@ public:
ProcessExtraCompiler(const Project *project, const Utils::FileName &source,
const Utils::FileNameList &targets, QObject *parent = nullptr);
~ProcessExtraCompiler();
protected:
// This will run a process in a thread, if
......@@ -128,9 +129,10 @@ protected:
private:
using ContentProvider = std::function<QByteArray()>;
void runImpl(const ContentProvider &sourceContents);
FileNameToContentsHash runInThread(const Utils::FileName &cmd, const Utils::FileName &workDir,
const QStringList &args, const ContentProvider &provider,
const Utils::Environment &env);
void runInThread(QFutureInterface<FileNameToContentsHash> &futureInterface,
const Utils::FileName &cmd, const Utils::FileName &workDir,
const QStringList &args, const ContentProvider &provider,
const Utils::Environment &env);
void cleanUp();
QFutureWatcher<FileNameToContentsHash> *m_watcher = nullptr;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment