forked from qt-creator/qt-creator
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:
committed by
Orgad Shaneh
parent
f589e8b38d
commit
e883650ed5
@@ -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;
|
||||
|
Reference in New Issue
Block a user