diff options
author | Jarek Kobus <jaroslaw.kobus@qt.io> | 2021-10-01 10:56:52 +0200 |
---|---|---|
committer | Jarek Kobus <jaroslaw.kobus@qt.io> | 2021-10-06 09:57:37 +0000 |
commit | 7e7b6a52f9bbe105e08b7860ae993a1faa45d636 (patch) | |
tree | c3e4f3fe09b86c4703b507ecf48fb51ccea55f0b | |
parent | 704a758f69d43df8b772147bb5ebe03126335212 (diff) |
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: a30aa4421a0257b048197b51330e6bf5c2732af5
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>
-rw-r--r-- | src/plugins/qmakeprojectmanager/qmakeproject.cpp | 3 | ||||
-rw-r--r-- | src/shared/proparser/qmakebuiltins.cpp | 27 | ||||
-rw-r--r-- | src/shared/proparser/qmakeglobals.cpp | 4 | ||||
-rw-r--r-- | src/shared/proparser/qmakeglobals.h | 3 |
4 files changed, 19 insertions, 18 deletions
diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp index 793ec73ba8..54395bfc37 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp @@ -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(); diff --git a/src/shared/proparser/qmakebuiltins.cpp b/src/shared/proparser/qmakebuiltins.cpp index a697133896..c47bc1b2e7 100644 --- a/src/shared/proparser/qmakebuiltins.cpp +++ b/src/shared/proparser/qmakebuiltins.cpp @@ -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 diff --git a/src/shared/proparser/qmakeglobals.cpp b/src/shared/proparser/qmakeglobals.cpp index ea429145e3..ca22bdde8b 100644 --- a/src/shared/proparser/qmakeglobals.cpp +++ b/src/shared/proparser/qmakeglobals.cpp @@ -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 } diff --git a/src/shared/proparser/qmakeglobals.h b/src/shared/proparser/qmakeglobals.h index 2fa9a33213..2baeab4bf5 100644 --- a/src/shared/proparser/qmakeglobals.h +++ b/src/shared/proparser/qmakeglobals.h @@ -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; |