Commit 962ba86d authored by Tobias Hunger's avatar Tobias Hunger

AbstractProcessStep: Do not run a qprocess in a thread

This avoids sending signals for new tasks and process output
via the gui thread's event loop. When finding lots of issues in
the output we generate so many events that any attempt to
compress events takes a long time (max. events waiting to be
processed were > 1200000 when doing a clang -Weverything build!),
and thus the UI freezes.

Change-Id: I9668d2537b1a268e788cd0ea5c756ebaab4462a9
Reviewed-by: default avatarDaniel Teske <daniel.teske@digia.com>
parent 6a7cefbd
......@@ -184,6 +184,7 @@ void AutogenStep::run(QFutureInterface<bool> &interface)
if (!m_runAutogen) {
emit addOutput(tr("Configuration unchanged, skipping autogen step."), BuildStep::MessageOutput);
interface.reportResult(true);
emit finished();
return;
}
......
......@@ -178,6 +178,7 @@ void AutoreconfStep::run(QFutureInterface<bool> &interface)
if (!m_runAutoreconf) {
emit addOutput(tr("Configuration unchanged, skipping autoreconf step."), BuildStep::MessageOutput);
interface.reportResult(true);
emit finished();
return;
}
......
......@@ -182,6 +182,7 @@ void ConfigureStep::run(QFutureInterface<bool>& interface)
if (!m_runConfigure) {
emit addOutput(tr("Configuration unchanged, skipping configure step."), BuildStep::MessageOutput);
interface.reportResult(true);
emit finished();
return;
}
......
......@@ -211,6 +211,7 @@ void MakeStep::run(QFutureInterface<bool> &interface)
if (!canContinue) {
emit addOutput(tr("Configuration is faulty. Check the Issues view for details."), BuildStep::MessageOutput);
interface.reportResult(false);
emit finished();
return;
}
......
......@@ -219,6 +219,7 @@ void MakeStep::run(QFutureInterface<bool> &fi)
if (!canContinue) {
emit addOutput(tr("Configuration is faulty. Check the Issues view for details."), BuildStep::MessageOutput);
fi.reportResult(false);
emit finished();
return;
}
......
......@@ -198,6 +198,7 @@ void GenericMakeStep::run(QFutureInterface<bool> &fi)
if (!canContinue) {
emit addOutput(tr("Configuration is faulty. Check the Issues view for details."), BuildStep::MessageOutput);
fi.reportResult(false);
emit finished();
return;
}
......
......@@ -91,7 +91,7 @@ using namespace ProjectExplorer;
AbstractProcessStep::AbstractProcessStep(BuildStepList *bsl, const Core::Id id) :
BuildStep(bsl, id), m_timer(0), m_futureInterface(0),
m_ignoreReturnValue(false), m_process(0),
m_eventLoop(0), m_outputParserChain(0)
m_outputParserChain(0)
{
}
......@@ -99,7 +99,7 @@ AbstractProcessStep::AbstractProcessStep(BuildStepList *bsl,
AbstractProcessStep *bs) :
BuildStep(bsl, bs), m_timer(0), m_futureInterface(0),
m_ignoreReturnValue(bs->m_ignoreReturnValue),
m_process(0), m_eventLoop(0), m_outputParserChain(0)
m_process(0), m_outputParserChain(0)
{
}
......@@ -197,15 +197,12 @@ void AbstractProcessStep::run(QFutureInterface<bool> &fi)
m_process->setEnvironment(m_param.environment());
connect(m_process, SIGNAL(readyReadStandardOutput()),
this, SLOT(processReadyReadStdOutput()),
Qt::DirectConnection);
this, SLOT(processReadyReadStdOutput()));
connect(m_process, SIGNAL(readyReadStandardError()),
this, SLOT(processReadyReadStdError()),
Qt::DirectConnection);
this, SLOT(processReadyReadStdError()));
connect(m_process, SIGNAL(finished(int,QProcess::ExitStatus)),
this, SLOT(slotProcessFinished(int,QProcess::ExitStatus)),
Qt::DirectConnection);
this, SLOT(slotProcessFinished(int,QProcess::ExitStatus)));
m_process->setCommand(m_param.effectiveCommand(), m_param.effectiveArguments());
m_process->start();
......@@ -214,19 +211,19 @@ void AbstractProcessStep::run(QFutureInterface<bool> &fi)
delete m_process;
m_process = 0;
fi.reportResult(false);
emit finished();
return;
}
processStarted();
m_timer = new QTimer();
connect(m_timer, SIGNAL(timeout()), this, SLOT(checkForCancel()), Qt::DirectConnection);
connect(m_timer, SIGNAL(timeout()), this, SLOT(checkForCancel()));
m_timer->start(500);
m_eventLoop = new QEventLoop;
m_eventLoop->exec();
m_timer->stop();
delete m_timer;
m_timer = 0;
m_killProcess = false;
}
void AbstractProcessStep::cleanUp()
{
// The process has finished, leftover data is read in processFinished
processFinished(m_process->exitCode(), m_process->exitStatus());
bool returnValue = processSucceeded(m_process->exitCode(), m_process->exitStatus()) || m_ignoreReturnValue;
......@@ -239,11 +236,10 @@ void AbstractProcessStep::run(QFutureInterface<bool> &fi)
delete m_process;
m_process = 0;
delete m_eventLoop;
m_eventLoop = 0;
fi.reportResult(returnValue);
m_futureInterface->reportResult(returnValue);
m_futureInterface = 0;
return;
emit finished();
}
/*!
......@@ -351,10 +347,14 @@ void AbstractProcessStep::stdError(const QString &line)
void AbstractProcessStep::checkForCancel()
{
if (m_futureInterface->isCanceled() && m_timer->isActive()) {
m_timer->stop();
m_process->terminate();
m_process->waitForFinished(5000);
m_process->kill();
if (!m_killProcess) {
m_process->terminate();
m_timer->start(5000);
m_killProcess = true;
} else {
m_process->kill();
m_timer->stop();
}
}
}
......@@ -413,6 +413,10 @@ void AbstractProcessStep::outputAdded(const QString &string, ProjectExplorer::Bu
void AbstractProcessStep::slotProcessFinished(int, QProcess::ExitStatus)
{
m_timer->stop();
delete m_timer;
m_timer = 0;
QString line = QString::fromLocal8Bit(m_process->readAllStandardError());
if (!line.isEmpty())
stdError(line);
......@@ -421,5 +425,5 @@ void AbstractProcessStep::slotProcessFinished(int, QProcess::ExitStatus)
if (!line.isEmpty())
stdOutput(line);
m_eventLoop->exit(0);
cleanUp();
}
......@@ -57,6 +57,7 @@ public:
virtual bool init();
virtual void run(QFutureInterface<bool> &);
bool runInGuiThread() const { return true; }
ProcessParameters *processParameters() { return &m_param; }
......@@ -83,6 +84,8 @@ private slots:
void slotProcessFinished(int, QProcess::ExitStatus);
void checkForCancel();
void cleanUp();
void taskAdded(const ProjectExplorer::Task &task);
void outputAdded(const QString &string, ProjectExplorer::BuildStep::OutputFormat format);
......@@ -95,6 +98,7 @@ private:
Utils::QtcProcess *m_process;
QEventLoop *m_eventLoop;
ProjectExplorer::IOutputParser *m_outputParserChain;
bool m_killProcess;
};
} // namespace ProjectExplorer
......
......@@ -265,11 +265,13 @@ void MakeStep::run(QFutureInterface<bool> & fi)
if (!canContinue) {
emit addOutput(tr("Configuration is faulty. Check the Issues view for details."), BuildStep::MessageOutput);
fi.reportResult(false);
emit finished();
return;
}
if (m_scriptTarget) {
fi.reportResult(true);
emit finished();
return;
}
......@@ -277,6 +279,7 @@ void MakeStep::run(QFutureInterface<bool> & fi)
if (!ignoreReturnValue())
emit addOutput(tr("Cannot find Makefile. Check your build settings."), BuildStep::MessageOutput);
fi.reportResult(ignoreReturnValue());
emit finished();
return;
}
......
......@@ -322,12 +322,14 @@ void QMakeStep::run(QFutureInterface<bool> &fi)
if (!canContinue) {
emit addOutput(tr("Configuration is faulty, please check the Issues view for details."), BuildStep::MessageOutput);
fi.reportResult(false);
emit finished();
return;
}
if (!m_needToRunQMake) {
emit addOutput(tr("Configuration unchanged, skipping qmake step."), BuildStep::MessageOutput);
fi.reportResult(true);
emit finished();
return;
}
......
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