Commit 96630673 authored by dt's avatar dt
Browse files

Fix deadlock in .pro file evaluation.

We used to indicate that the cache for a file is up to date by having a
Entry with ent->locker == 0. But we first wake up all threads and only
after all the threads who waited for that parse to complete we set
ent->locker to zero. Thus a different thread could get the impression
that it needs to wait for the parse thread, yet get no wake up.

We need a different flag to indicate that we are actually already done
parsing and the cache can simply be used instead of waiting for a wake
up.

Reviewed-By: ossi
parent b6fda5be
...@@ -3031,7 +3031,7 @@ ProFile *ProFileEvaluator::Private::parsedProFile(const QString &fileName, bool ...@@ -3031,7 +3031,7 @@ ProFile *ProFileEvaluator::Private::parsedProFile(const QString &fileName, bool
if (it != m_option->cache->parsed_files.end()) { if (it != m_option->cache->parsed_files.end()) {
ent = &*it; ent = &*it;
#ifdef PROPARSER_THREAD_SAFE #ifdef PROPARSER_THREAD_SAFE
if (ent->locker) { if (ent->locker && !ent->locker->done) {
++ent->locker->waiters; ++ent->locker->waiters;
QThreadPool::globalInstance()->releaseThread(); QThreadPool::globalInstance()->releaseThread();
ent->locker->cond.wait(locker.mutex()); ent->locker->cond.wait(locker.mutex());
...@@ -3061,6 +3061,7 @@ ProFile *ProFileEvaluator::Private::parsedProFile(const QString &fileName, bool ...@@ -3061,6 +3061,7 @@ ProFile *ProFileEvaluator::Private::parsedProFile(const QString &fileName, bool
#ifdef PROPARSER_THREAD_SAFE #ifdef PROPARSER_THREAD_SAFE
locker.relock(); locker.relock();
if (ent->locker->waiters) { if (ent->locker->waiters) {
ent->locker->done = true;
ent->locker->cond.wakeAll(); ent->locker->cond.wakeAll();
} else { } else {
delete ent->locker; delete ent->locker;
......
...@@ -123,9 +123,10 @@ private: ...@@ -123,9 +123,10 @@ private:
ProFile *pro; ProFile *pro;
#ifdef PROPARSER_THREAD_SAFE #ifdef PROPARSER_THREAD_SAFE
struct Locker { struct Locker {
Locker() : waiters(0) {} Locker() : waiters(0), done(false) {}
QWaitCondition cond; QWaitCondition cond;
int waiters; int waiters;
bool done;
}; };
Locker *locker; Locker *locker;
#endif #endif
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment