Don't kill the QProcess instance which is running in other thread

The main thread doesn't kill processes directly, but
sets just the cancel flag.

Instead of waiting infinitely long for a process to finish
we poll periodically (every 100ms) for the canceled flag
inside the thread that started the process.

Amends: a30aa4421a

Task-number: QTCREATORBUG-26333
Change-Id: I599d5c6cd69381cadc4a01c65f6a79f9a9bbd3fb
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
Jarek Kobus
2021-10-01 10:56:52 +02:00
parent 704a758f69
commit 7e7b6a52f9
4 changed files with 19 additions and 18 deletions

View File

@@ -674,8 +674,9 @@ void QmakeBuildSystem::asyncUpdate()
connect(watcher, &QFutureWatcher<void>::canceled, this, [this, watcher] {
if (!m_qmakeGlobals)
return;
watcher->disconnect();
m_qmakeGlobals->killProcesses();
watcher->disconnect();
watcher->deleteLater();
});
connect(watcher, &QFutureWatcher<void>::finished, this, [watcher] {
watcher->disconnect();

View File

@@ -474,12 +474,8 @@ void QMakeEvaluator::runProcess(QProcess *proc, const QString &command) const
}
# endif
# ifdef PROEVALUATOR_THREAD_SAFE
m_option->mutex.lock();
if (m_option->canceled) {
m_option->mutex.unlock();
if (m_option->canceled)
return;
}
m_option->runningProcs << proc;
# endif
# ifdef Q_OS_WIN
proc->setNativeArguments(QLatin1String("/v:off /s /c \"") + command + QLatin1Char('"'));
@@ -488,12 +484,21 @@ void QMakeEvaluator::runProcess(QProcess *proc, const QString &command) const
proc->start(QLatin1String("/bin/sh"), QStringList() << QLatin1String("-c") << command);
# endif
# ifdef PROEVALUATOR_THREAD_SAFE
m_option->mutex.unlock();
# endif
proc->waitForFinished(-1);
# ifdef PROEVALUATOR_THREAD_SAFE
QMutexLocker(&m_option->mutex);
m_option->runningProcs.removeOne(proc);
while (true) {
if (proc->waitForFinished(100))
break;
if (m_option->canceled) {
proc->terminate();
if (proc->waitForFinished(1000))
break;
proc->kill();
proc->waitForFinished(1000);
break;
}
}
# else
proc->waitForFinished(-1); // If have have single thread we can't cancel it using
// synchronous API of QProcess
# endif
}
#endif

View File

@@ -92,11 +92,7 @@ QMakeGlobals::~QMakeGlobals()
void QMakeGlobals::killProcesses()
{
#ifdef PROEVALUATOR_THREAD_SAFE
QMutexLocker lock(&mutex);
canceled = true;
for (QProcess * const proc : runningProcs)
proc->kill();
runningProcs.clear();
#endif
}

View File

@@ -159,8 +159,7 @@ private:
#ifdef PROEVALUATOR_THREAD_SAFE
QMutex mutex;
bool canceled = false;
QList<QProcess *> runningProcs;
std::atomic_bool canceled = false;
#endif
QHash<QMakeBaseKey, QMakeBaseEnv *> baseEnvs;