forked from qt-creator/qt-creator
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:
@@ -674,8 +674,9 @@ void QmakeBuildSystem::asyncUpdate()
|
|||||||
connect(watcher, &QFutureWatcher<void>::canceled, this, [this, watcher] {
|
connect(watcher, &QFutureWatcher<void>::canceled, this, [this, watcher] {
|
||||||
if (!m_qmakeGlobals)
|
if (!m_qmakeGlobals)
|
||||||
return;
|
return;
|
||||||
watcher->disconnect();
|
|
||||||
m_qmakeGlobals->killProcesses();
|
m_qmakeGlobals->killProcesses();
|
||||||
|
watcher->disconnect();
|
||||||
|
watcher->deleteLater();
|
||||||
});
|
});
|
||||||
connect(watcher, &QFutureWatcher<void>::finished, this, [watcher] {
|
connect(watcher, &QFutureWatcher<void>::finished, this, [watcher] {
|
||||||
watcher->disconnect();
|
watcher->disconnect();
|
||||||
|
@@ -474,12 +474,8 @@ void QMakeEvaluator::runProcess(QProcess *proc, const QString &command) const
|
|||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
# ifdef PROEVALUATOR_THREAD_SAFE
|
# ifdef PROEVALUATOR_THREAD_SAFE
|
||||||
m_option->mutex.lock();
|
if (m_option->canceled)
|
||||||
if (m_option->canceled) {
|
|
||||||
m_option->mutex.unlock();
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
m_option->runningProcs << proc;
|
|
||||||
# endif
|
# endif
|
||||||
# ifdef Q_OS_WIN
|
# ifdef Q_OS_WIN
|
||||||
proc->setNativeArguments(QLatin1String("/v:off /s /c \"") + command + QLatin1Char('"'));
|
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);
|
proc->start(QLatin1String("/bin/sh"), QStringList() << QLatin1String("-c") << command);
|
||||||
# endif
|
# endif
|
||||||
# ifdef PROEVALUATOR_THREAD_SAFE
|
# ifdef PROEVALUATOR_THREAD_SAFE
|
||||||
m_option->mutex.unlock();
|
while (true) {
|
||||||
# endif
|
if (proc->waitForFinished(100))
|
||||||
proc->waitForFinished(-1);
|
break;
|
||||||
# ifdef PROEVALUATOR_THREAD_SAFE
|
if (m_option->canceled) {
|
||||||
QMutexLocker(&m_option->mutex);
|
proc->terminate();
|
||||||
m_option->runningProcs.removeOne(proc);
|
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
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -92,11 +92,7 @@ QMakeGlobals::~QMakeGlobals()
|
|||||||
void QMakeGlobals::killProcesses()
|
void QMakeGlobals::killProcesses()
|
||||||
{
|
{
|
||||||
#ifdef PROEVALUATOR_THREAD_SAFE
|
#ifdef PROEVALUATOR_THREAD_SAFE
|
||||||
QMutexLocker lock(&mutex);
|
|
||||||
canceled = true;
|
canceled = true;
|
||||||
for (QProcess * const proc : runningProcs)
|
|
||||||
proc->kill();
|
|
||||||
runningProcs.clear();
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -159,8 +159,7 @@ private:
|
|||||||
|
|
||||||
#ifdef PROEVALUATOR_THREAD_SAFE
|
#ifdef PROEVALUATOR_THREAD_SAFE
|
||||||
QMutex mutex;
|
QMutex mutex;
|
||||||
bool canceled = false;
|
std::atomic_bool canceled = false;
|
||||||
QList<QProcess *> runningProcs;
|
|
||||||
#endif
|
#endif
|
||||||
QHash<QMakeBaseKey, QMakeBaseEnv *> baseEnvs;
|
QHash<QMakeBaseKey, QMakeBaseEnv *> baseEnvs;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user