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)
|
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);
|
||||||
|
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.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...
|
||||||
|
@@ -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,9 +129,10 @@ 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 QStringList &args, const ContentProvider &provider,
|
const Utils::FileName &cmd, const Utils::FileName &workDir,
|
||||||
const Utils::Environment &env);
|
const QStringList &args, const ContentProvider &provider,
|
||||||
|
const Utils::Environment &env);
|
||||||
void cleanUp();
|
void cleanUp();
|
||||||
|
|
||||||
QFutureWatcher<FileNameToContentsHash> *m_watcher = nullptr;
|
QFutureWatcher<FileNameToContentsHash> *m_watcher = nullptr;
|
||||||
|
Reference in New Issue
Block a user