forked from qt-creator/qt-creator
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: Daniel Teske <daniel.teske@digia.com>
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user