From: Oswald Buddenhagen Date: Tue, 23 Jul 2013 15:57:44 +0000 (+0200) Subject: lock baseEnv in cache() X-Git-Tag: accepted/tizen/20131212.181521~83^2~11 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4da64094c8dac54fc806f98fa60fcd91cf4d3df9;p=platform%2Fupstream%2Fqttools.git lock baseEnv in cache() sync up; doesn't do anything in lupdate. as we modify the environment, it must be properly locked. this implies that initFrom() also needs to be called with a lock. Change-Id: I48bae9af9adaa0518e5a9db0ba08ff057ae14f9f Reviewed-by: Joerg Bornemann (cherry picked from qtcreator/d022a2d19cecb00397c2a215fc4e3bf64b1e627b) --- diff --git a/src/linguist/shared/qmakebuiltins.cpp b/src/linguist/shared/qmakebuiltins.cpp index b4694cf..37654a2 100644 --- a/src/linguist/shared/qmakebuiltins.cpp +++ b/src/linguist/shared/qmakebuiltins.cpp @@ -56,6 +56,9 @@ #include #include #include +#ifdef PROEVALUATOR_THREAD_SAFE +# include +#endif #ifdef Q_OS_UNIX #include @@ -1540,8 +1543,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) { @@ -1572,7 +1598,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( } changed = true; } - } + } while (false); if (hostBuild) break; } diff --git a/src/linguist/shared/qmakeevaluator.cpp b/src/linguist/shared/qmakeevaluator.cpp index 67aeb11..18cb6e9 100644 --- a/src/linguist/shared/qmakeevaluator.cpp +++ b/src/linguist/shared/qmakeevaluator.cpp @@ -1319,47 +1319,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);