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