From 966306735799fc9feb81b0bef57809b3608574b3 Mon Sep 17 00:00:00 2001 From: dt <qtc-committer@nokia.com> Date: Wed, 17 Mar 2010 16:19:55 +0100 Subject: [PATCH] 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 --- src/shared/proparser/profileevaluator.cpp | 3 ++- src/shared/proparser/profileevaluator.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/shared/proparser/profileevaluator.cpp b/src/shared/proparser/profileevaluator.cpp index de8561a21e3..c883ba835ee 100644 --- a/src/shared/proparser/profileevaluator.cpp +++ b/src/shared/proparser/profileevaluator.cpp @@ -3031,7 +3031,7 @@ ProFile *ProFileEvaluator::Private::parsedProFile(const QString &fileName, bool if (it != m_option->cache->parsed_files.end()) { ent = &*it; #ifdef PROPARSER_THREAD_SAFE - if (ent->locker) { + if (ent->locker && !ent->locker->done) { ++ent->locker->waiters; QThreadPool::globalInstance()->releaseThread(); ent->locker->cond.wait(locker.mutex()); @@ -3061,6 +3061,7 @@ ProFile *ProFileEvaluator::Private::parsedProFile(const QString &fileName, bool #ifdef PROPARSER_THREAD_SAFE locker.relock(); if (ent->locker->waiters) { + ent->locker->done = true; ent->locker->cond.wakeAll(); } else { delete ent->locker; diff --git a/src/shared/proparser/profileevaluator.h b/src/shared/proparser/profileevaluator.h index 746293214e1..e4acafdd36a 100644 --- a/src/shared/proparser/profileevaluator.h +++ b/src/shared/proparser/profileevaluator.h @@ -123,9 +123,10 @@ private: ProFile *pro; #ifdef PROPARSER_THREAD_SAFE struct Locker { - Locker() : waiters(0) {} + Locker() : waiters(0), done(false) {} QWaitCondition cond; int waiters; + bool done; }; Locker *locker; #endif -- GitLab