Fix infinite QWaitCondition:wait() in discardFile*()

The original idea was that we would passively wait for another thread to
clean up the locker, hence the check-sleep-loop. This was all dandy,
except for *also* using the wait condition: this was a) mostly pointless
(it would just avoid a few iterations of the wait loop) and b) buggy (if
there were no other waiting threads, the actual reader thread wouldn't
know that it needs to wake somebody up).
As the passive waiting is ugly, we instead fix the use of the wait
condition, and do away with the loop.

Task-number: QTCREATORBUG-15181
Change-Id: I477dbe7cda49ceca9aa387910d94ad763a43012b
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
Reviewed-by: Daniel Teske <daniel.teske@theqtcompany.com>
This commit is contained in:
Daniel Teske
2015-10-14 11:59:46 +02:00
parent 7c2761f1f0
commit a027cbcd70

View File

@@ -63,13 +63,14 @@ void ProFileCache::discardFile(const QString &fileName)
if (it != parsed_files.end()) {
#ifdef PROPARSER_THREAD_SAFE
if (it->locker) {
if (!it->locker->done)
if (!it->locker->done) {
++it->locker->waiters;
it->locker->cond.wait(&mutex);
do {
lck.unlock();
QThread::sleep(100);
lck.relock();
} while (it->locker);
if (!--it->locker->waiters) {
delete it->locker;
it->locker = 0;
}
}
}
#endif
if (it->pro)
@@ -90,13 +91,14 @@ void ProFileCache::discardFiles(const QString &prefix)
if (it.key().startsWith(prefix)) {
#ifdef PROPARSER_THREAD_SAFE
if (it->locker) {
if (!it->locker->done)
if (!it->locker->done) {
++it->locker->waiters;
it->locker->cond.wait(&mutex);
do {
lck.unlock();
QThread::sleep(100);
lck.relock();
} while (it->locker);
if (!--it->locker->waiters) {
delete it->locker;
it->locker = 0;
}
}
}
#endif
if (it->pro)
@@ -107,7 +109,6 @@ void ProFileCache::discardFiles(const QString &prefix)
}
}
////////// Parser ///////////
#define fL1S(s) QString::fromLatin1(s)