forked from qt-creator/qt-creator
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
This commit is contained in:
@@ -96,7 +96,7 @@ FORMS += makestep.ui \
|
|||||||
wizards/targetsetuppage.ui
|
wizards/targetsetuppage.ui
|
||||||
RESOURCES += qt4projectmanager.qrc \
|
RESOURCES += qt4projectmanager.qrc \
|
||||||
wizards/wizards.qrc
|
wizards/wizards.qrc
|
||||||
DEFINES += PROPARSER_THREAD_SAFE
|
DEFINES += PROPARSER_THREAD_SAFE PROEVALUATOR_THREAD_SAFE
|
||||||
include(../../shared/proparser/proparser.pri)
|
include(../../shared/proparser/proparser.pri)
|
||||||
include(qt-s60/qt-s60.pri)
|
include(qt-s60/qt-s60.pri)
|
||||||
include(qt-maemo/qt-maemo.pri)
|
include(qt-maemo/qt-maemo.pri)
|
||||||
|
|||||||
@@ -161,6 +161,10 @@ ProFileOption::ProFileOption()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
cache = 0;
|
cache = 0;
|
||||||
|
|
||||||
|
#ifdef PROEVALUATOR_THREAD_SAFE
|
||||||
|
base_inProgress = false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ProFileOption::~ProFileOption()
|
ProFileOption::~ProFileOption()
|
||||||
@@ -1270,7 +1274,21 @@ ProItem::ProItemReturn ProFileEvaluator::Private::visitProFile(ProFile *pro)
|
|||||||
|
|
||||||
if (m_parsePreAndPostFiles) {
|
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()) {
|
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_QMAKE, QMAKE_SH
|
||||||
// ### init QMAKE_EXT_{C,H,CPP,OBJ}
|
// ### init QMAKE_EXT_{C,H,CPP,OBJ}
|
||||||
// ### init TEMPLATE_PREFIX
|
// ### init TEMPLATE_PREFIX
|
||||||
@@ -1377,7 +1395,16 @@ ProItem::ProItemReturn ProFileEvaluator::Private::visitProFile(ProFile *pro)
|
|||||||
|
|
||||||
evaluateFeatureFile(QLatin1String("default_pre.prf"),
|
evaluateFeatureFile(QLatin1String("default_pre.prf"),
|
||||||
&m_option->base_valuemap, &m_option->base_functions);
|
&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;
|
m_valuemapStack.top() = m_option->base_valuemap;
|
||||||
|
|
||||||
|
|||||||
@@ -182,6 +182,11 @@ struct ProFileOption
|
|||||||
ProFileEvaluator::FunctionDefs base_functions;
|
ProFileEvaluator::FunctionDefs base_functions;
|
||||||
QStringList feature_roots;
|
QStringList feature_roots;
|
||||||
QString qmakespec_name;
|
QString qmakespec_name;
|
||||||
|
#ifdef PROEVALUATOR_THREAD_SAFE
|
||||||
|
QMutex mutex;
|
||||||
|
QWaitCondition cond;
|
||||||
|
bool base_inProgress;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|||||||
Reference in New Issue
Block a user