summaryrefslogtreecommitdiffstats
path: root/qmake
diff options
context:
space:
mode:
authorOswald Buddenhagen <oswald.buddenhagen@digia.com>2013-07-23 17:57:44 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-08-27 13:36:31 +0200
commit652bdb8894c249641beb0b8e97af459d4518cd28 (patch)
tree30cbd6d21a86d20b3bdcd6806d669b9beff729ca /qmake
parent957134dc84ed06d31217fdd79b322d9ed5d096e8 (diff)
lock baseEnv in cache()
sync up; this doesn't actually do anything in qmake. as we modify the environment, it must be properly locked. this implies that initFrom() also needs to be called with a lock. Task-number: QTCREATORBUG-9835 Change-Id: I48bae9af9adaa0518e5a9db0ba08ff057ae14f9f Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com> (cherry picked from qtcreator/d022a2d19cecb00397c2a215fc4e3bf64b1e627b)
Diffstat (limited to 'qmake')
-rw-r--r--qmake/library/qmakebuiltins.cpp32
-rw-r--r--qmake/library/qmakeevaluator.cpp60
2 files changed, 58 insertions, 34 deletions
diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp
index c0f1724563..aec8d70041 100644
--- a/qmake/library/qmakebuiltins.cpp
+++ b/qmake/library/qmakebuiltins.cpp
@@ -56,6 +56,9 @@
#include <qset.h>
#include <qstringlist.h>
#include <qtextstream.h>
+#ifdef PROEVALUATOR_THREAD_SAFE
+# include <qthreadpool.h>
+#endif
#ifdef Q_OS_UNIX
#include <time.h>
@@ -1538,8 +1541,31 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
ProStringList newval;
bool changed = false;
for (bool hostBuild = false; ; hostBuild = true) {
- if (QMakeBaseEnv *baseEnv = m_option->baseEnvs.value(
- QMakeBaseKey(m_buildRoot, hostBuild))) {
+#ifdef PROEVALUATOR_THREAD_SAFE
+ m_option->mutex.lock();
+#endif
+ QMakeBaseEnv *baseEnv =
+ m_option->baseEnvs.value(QMakeBaseKey(m_buildRoot, hostBuild));
+#ifdef PROEVALUATOR_THREAD_SAFE
+ // It's ok to unlock this before locking baseEnv,
+ // as we have no intention to initialize the env.
+ m_option->mutex.unlock();
+#endif
+ do {
+ if (!baseEnv)
+ break;
+#ifdef PROEVALUATOR_THREAD_SAFE
+ QMutexLocker locker(&baseEnv->mutex);
+ if (baseEnv->inProgress) {
+ // The env is still in the works, but it may be already past the cache
+ // loading. So we need to wait for completion and amend it as usual.
+ QThreadPool::globalInstance()->releaseThread();
+ baseEnv->cond.wait(&baseEnv->mutex);
+ QThreadPool::globalInstance()->reserveThread();
+ }
+ if (!baseEnv->isOk)
+ break;
+#endif
QMakeEvaluator *baseEval = baseEnv->evaluator;
const ProStringList &oldval = baseEval->values(dstvar);
if (mode == CacheSet) {
@@ -1570,7 +1596,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
}
changed = true;
}
- }
+ } while (false);
if (hostBuild)
break;
}
diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp
index b898929535..0df69890b3 100644
--- a/qmake/library/qmakeevaluator.cpp
+++ b/qmake/library/qmakeevaluator.cpp
@@ -1317,47 +1317,45 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProFile(
QMakeBaseEnv *baseEnv = *baseEnvPtr;
#ifdef PROEVALUATOR_THREAD_SAFE
- {
- QMutexLocker locker(&baseEnv->mutex);
- m_option->mutex.unlock();
- if (baseEnv->inProgress) {
- QThreadPool::globalInstance()->releaseThread();
- baseEnv->cond.wait(&baseEnv->mutex);
- QThreadPool::globalInstance()->reserveThread();
- if (!baseEnv->isOk)
- return ReturnFalse;
- } else
+ QMutexLocker locker(&baseEnv->mutex);
+ m_option->mutex.unlock();
+ if (baseEnv->inProgress) {
+ QThreadPool::globalInstance()->releaseThread();
+ baseEnv->cond.wait(&baseEnv->mutex);
+ QThreadPool::globalInstance()->reserveThread();
+ if (!baseEnv->isOk)
+ return ReturnFalse;
+ } else
#endif
- if (!baseEnv->evaluator) {
+ if (!baseEnv->evaluator) {
#ifdef PROEVALUATOR_THREAD_SAFE
- baseEnv->inProgress = true;
- locker.unlock();
+ baseEnv->inProgress = true;
+ locker.unlock();
#endif
- QMakeEvaluator *baseEval = new QMakeEvaluator(m_option, m_parser, m_vfs, m_handler);
- baseEnv->evaluator = baseEval;
- baseEval->m_superfile = m_superfile;
- baseEval->m_conffile = m_conffile;
- baseEval->m_cachefile = m_cachefile;
- baseEval->m_sourceRoot = m_sourceRoot;
- baseEval->m_buildRoot = m_buildRoot;
- baseEval->m_hostBuild = m_hostBuild;
- bool ok = baseEval->loadSpec();
+ QMakeEvaluator *baseEval = new QMakeEvaluator(m_option, m_parser, m_vfs, m_handler);
+ baseEnv->evaluator = baseEval;
+ baseEval->m_superfile = m_superfile;
+ baseEval->m_conffile = m_conffile;
+ baseEval->m_cachefile = m_cachefile;
+ baseEval->m_sourceRoot = m_sourceRoot;
+ baseEval->m_buildRoot = m_buildRoot;
+ baseEval->m_hostBuild = m_hostBuild;
+ bool ok = baseEval->loadSpec();
#ifdef PROEVALUATOR_THREAD_SAFE
- locker.relock();
- baseEnv->isOk = ok;
- baseEnv->inProgress = false;
- baseEnv->cond.wakeAll();
+ locker.relock();
+ baseEnv->isOk = ok;
+ baseEnv->inProgress = false;
+ baseEnv->cond.wakeAll();
#endif
- if (!ok)
- return ReturnFalse;
- }
-#ifdef PROEVALUATOR_THREAD_SAFE
- else if (!baseEnv->isOk)
+ if (!ok)
return ReturnFalse;
}
+#ifdef PROEVALUATOR_THREAD_SAFE
+ else if (!baseEnv->isOk)
+ return ReturnFalse;
#endif
initFrom(*baseEnv->evaluator);