summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOswald Buddenhagen <oswald.buddenhagen@nokia.com>2010-06-04 17:08:27 +0200
committerOswald Buddenhagen <oswald.buddenhagen@nokia.com>2010-06-04 17:58:41 +0200
commit0059bc7bb17d59202f8a1743b3f8946d4c8598a6 (patch)
tree742250a447de769e7fd8dae2ea1e72ea493333bb
parent01485e2c57fc14a1f2bfdd0d484f8e3184ecb6ad (diff)
downloadqt-creator-0059bc7bb17d59202f8a1743b3f8946d4c8598a6.tar.gz
make the evaluator (even more) thread-safe
the async re-parsing code breaks the assumption that project parsing only ever starts with a single non-concurrent evaluation (of the top-level project file), so the population of the base values in the shared ProFileOption was happily causing crashes. Reviewed-by: dt Task-number: QTCREATORBUG-1569
-rw-r--r--src/plugins/qt4projectmanager/qt4projectmanager.pro2
-rw-r--r--src/shared/proparser/profileevaluator.cpp27
-rw-r--r--src/shared/proparser/profileevaluator.h5
3 files changed, 33 insertions, 1 deletions
diff --git a/src/plugins/qt4projectmanager/qt4projectmanager.pro b/src/plugins/qt4projectmanager/qt4projectmanager.pro
index 448067a9e8..f4c492ac33 100644
--- a/src/plugins/qt4projectmanager/qt4projectmanager.pro
+++ b/src/plugins/qt4projectmanager/qt4projectmanager.pro
@@ -96,7 +96,7 @@ FORMS += makestep.ui \
wizards/targetsetuppage.ui
RESOURCES += qt4projectmanager.qrc \
wizards/wizards.qrc
-DEFINES += PROPARSER_THREAD_SAFE
+DEFINES += PROPARSER_THREAD_SAFE PROEVALUATOR_THREAD_SAFE
include(../../shared/proparser/proparser.pri)
include(qt-s60/qt-s60.pri)
include(qt-maemo/qt-maemo.pri)
diff --git a/src/shared/proparser/profileevaluator.cpp b/src/shared/proparser/profileevaluator.cpp
index 07717953b6..b4788904b0 100644
--- a/src/shared/proparser/profileevaluator.cpp
+++ b/src/shared/proparser/profileevaluator.cpp
@@ -161,6 +161,10 @@ ProFileOption::ProFileOption()
#endif
cache = 0;
+
+#ifdef PROEVALUATOR_THREAD_SAFE
+ base_inProgress = false;
+#endif
}
ProFileOption::~ProFileOption()
@@ -1270,7 +1274,21 @@ ProItem::ProItemReturn ProFileEvaluator::Private::visitProFile(ProFile *pro)
if (m_parsePreAndPostFiles) {
+#ifdef PROEVALUATOR_THREAD_SAFE
+ {
+ QMutexLocker locker(&m_option->mutex);
+ if (m_option->base_inProgress) {
+ QThreadPool::globalInstance()->releaseThread();
+ m_option->cond.wait(&m_option->mutex);
+ QThreadPool::globalInstance()->reserveThread();
+ } else
+#endif
if (m_option->base_valuemap.isEmpty()) {
+#ifdef PROEVALUATOR_THREAD_SAFE
+ m_option->base_inProgress = true;
+ locker.unlock();
+#endif
+
// ### init QMAKE_QMAKE, QMAKE_SH
// ### init QMAKE_EXT_{C,H,CPP,OBJ}
// ### init TEMPLATE_PREFIX
@@ -1377,7 +1395,16 @@ ProItem::ProItemReturn ProFileEvaluator::Private::visitProFile(ProFile *pro)
evaluateFeatureFile(QLatin1String("default_pre.prf"),
&m_option->base_valuemap, &m_option->base_functions);
+
+#ifdef PROEVALUATOR_THREAD_SAFE
+ locker.relock();
+ m_option->base_inProgress = false;
+ m_option->cond.wakeAll();
+#endif
}
+#ifdef PROEVALUATOR_THREAD_SAFE
+ }
+#endif
m_valuemapStack.top() = m_option->base_valuemap;
diff --git a/src/shared/proparser/profileevaluator.h b/src/shared/proparser/profileevaluator.h
index e4acafdd36..57df396d5a 100644
--- a/src/shared/proparser/profileevaluator.h
+++ b/src/shared/proparser/profileevaluator.h
@@ -182,6 +182,11 @@ struct ProFileOption
ProFileEvaluator::FunctionDefs base_functions;
QStringList feature_roots;
QString qmakespec_name;
+#ifdef PROEVALUATOR_THREAD_SAFE
+ QMutex mutex;
+ QWaitCondition cond;
+ bool base_inProgress;
+#endif
};
QT_END_NAMESPACE