diff --git a/language/backgroundparser/backgroundparser.h b/language/backgroundparser/backgroundparser.h --- a/language/backgroundparser/backgroundparser.h +++ b/language/backgroundparser/backgroundparser.h @@ -117,6 +117,8 @@ * */ DocumentChangeTracker* trackerForUrl(const IndexedString& url) const; + bool waitForIdle() const; + Q_SIGNALS: /** * Emitted whenever a document parse-job has finished. diff --git a/language/backgroundparser/backgroundparser.cpp b/language/backgroundparser/backgroundparser.cpp --- a/language/backgroundparser/backgroundparser.cpp +++ b/language/backgroundparser/backgroundparser.cpp @@ -23,6 +23,7 @@ #include "backgroundparser.h" +#include #include #include #include @@ -811,6 +812,30 @@ return d->m_managed.keys(); } + +bool BackgroundParser::waitForIdle() const +{ + QList runningParseJobsUrls; + forever { + { + QMutexLocker lock(&d->m_mutex); + if (d->m_parseJobs.isEmpty()) { + qCDebug(LANGUAGE) << "All parse jobs done" << d->m_parseJobs.keys(); + return true; + } + + if (d->m_parseJobs.size() != runningParseJobsUrls.size()) { + runningParseJobsUrls = d->m_parseJobs.keys(); + qCDebug(LANGUAGE) << "Waiting for background parser to get in idle state... -- the following parse jobs are still running:" << runningParseJobsUrls; + } + } + + QCoreApplication::processEvents(); + QThread::msleep(100); + } + return false; +} + DocumentChangeTracker* BackgroundParser::trackerForUrl(const KDevelop::IndexedString& url) const { if (url.isEmpty()) { diff --git a/shell/core.cpp b/shell/core.cpp --- a/shell/core.cpp +++ b/shell/core.cpp @@ -429,7 +429,7 @@ emit aboutToShutdown(); if (!d->m_cleanedUp) { - // first of all: stop background jobs + // first of all: request stop of all background parser jobs d->languageController->backgroundParser()->abortAllJobs(); d->languageController->backgroundParser()->suspend(); @@ -450,7 +450,11 @@ } d->projectController.data()->cleanup(); d->sourceFormatterController.data()->cleanup(); + + // before unloading language plugins, we need to make sure all parse jobs are done + d->languageController->backgroundParser()->waitForIdle(); d->pluginController.data()->cleanup(); + d->sessionController.data()->cleanup(); d->testController.data()->cleanup();