QmlJS: Fix deadlock when scanning apps

Change-Id: I7f8133eb634876b988675ed3b3cbebe596870a06
Reviewed-by: Dominik Holland <dominik.holland@qt.io>
This commit is contained in:
Marcus Tillmanns
2024-01-24 14:59:53 +01:00
parent 428898e6ba
commit 0414c4b67e
2 changed files with 25 additions and 13 deletions

View File

@@ -720,13 +720,13 @@ void ModelManagerInterface::updateDocument(const Document::Ptr &doc)
void ModelManagerInterface::updateLibraryInfo(const FilePath &path, void ModelManagerInterface::updateLibraryInfo(const FilePath &path,
const LibraryInfo &info, const LibraryInfo &info,
SyncedData &lockedData) SynchronizedValue<SyncedData>::unique_lock &lock)
{ {
if (!info.pluginTypeInfoError().isEmpty()) if (!info.pluginTypeInfoError().isEmpty())
qCDebug(qmljsLog) << "Dumping errors for " << path << ":" << info.pluginTypeInfoError(); qCDebug(qmljsLog) << "Dumping errors for " << path << ":" << info.pluginTypeInfoError();
lockedData.m_validSnapshot.insertLibraryInfo(path, info); lock->m_validSnapshot.insertLibraryInfo(path, info);
lockedData.m_newestSnapshot.insertLibraryInfo(path, info); lock->m_newestSnapshot.insertLibraryInfo(path, info);
// only emit if we got new useful information // only emit if we got new useful information
if (info.isValid()) if (info.isValid())
@@ -735,7 +735,8 @@ void ModelManagerInterface::updateLibraryInfo(const FilePath &path,
void ModelManagerInterface::updateLibraryInfo(const FilePath &path, const LibraryInfo &info) void ModelManagerInterface::updateLibraryInfo(const FilePath &path, const LibraryInfo &info)
{ {
m_syncedData.write([&path, &info, this](SyncedData &sd) { updateLibraryInfo(path, info, sd); }); SynchronizedValue<SyncedData>::unique_lock lock = m_syncedData.writeLocked();
updateLibraryInfo(path, info, lock);
} }
static QList<Utils::FilePath> filesInDirectoryForLanguages(const Utils::FilePath &path, static QList<Utils::FilePath> filesInDirectoryForLanguages(const Utils::FilePath &path,
@@ -836,10 +837,12 @@ static LibraryStatus libraryStatus(const FilePath &path,
: LibraryStatus::Unknown; : LibraryStatus::Unknown;
} }
static bool findNewQmlApplicationInPath(const FilePath &path, bool ModelManagerInterface::findNewQmlApplicationInPath(
const Snapshot &snapshot, const FilePath &path,
ModelManagerInterface *modelManager, const Snapshot &snapshot,
QSet<FilePath> *newLibraries) ModelManagerInterface *modelManager,
QSet<FilePath> *newLibraries,
SynchronizedValue<SyncedData>::unique_lock &lock)
{ {
switch (libraryStatus(path, snapshot, newLibraries)) { switch (libraryStatus(path, snapshot, newLibraries)) {
case LibraryStatus::Accepted: return true; case LibraryStatus::Accepted: return true;
@@ -860,8 +863,10 @@ static bool findNewQmlApplicationInPath(const FilePath &path,
LibraryInfo libraryInfo = LibraryInfo(qmltypesFile.toString()); LibraryInfo libraryInfo = LibraryInfo(qmltypesFile.toString());
const Utils::FilePath libraryPath = path.absolutePath(); const Utils::FilePath libraryPath = path.absolutePath();
newLibraries->insert(libraryPath); newLibraries->insert(libraryPath);
modelManager->updateLibraryInfo(path, libraryInfo); modelManager->updateLibraryInfo(path, libraryInfo, lock);
lock.unlock();
modelManager->loadPluginTypes(libraryPath.canonicalPath(), libraryPath, QString(), QString()); modelManager->loadPluginTypes(libraryPath.canonicalPath(), libraryPath, QString(), QString());
lock.lock();
return true; return true;
} }
@@ -885,7 +890,7 @@ bool ModelManagerInterface::findNewQmlLibraryInPath(const Utils::FilePath &path,
if (!ignoreMissing) { if (!ignoreMissing) {
LibraryInfo libraryInfo(LibraryInfo::NotFound); LibraryInfo libraryInfo(LibraryInfo::NotFound);
if (lock) if (lock)
modelManager->updateLibraryInfo(path, libraryInfo, **lock); modelManager->updateLibraryInfo(path, libraryInfo, *lock);
else else
modelManager->updateLibraryInfo(path, libraryInfo); modelManager->updateLibraryInfo(path, libraryInfo);
} }
@@ -908,7 +913,7 @@ bool ModelManagerInterface::findNewQmlLibraryInPath(const Utils::FilePath &path,
const Utils::FilePath libraryPath = qmldirFile.absolutePath(); const Utils::FilePath libraryPath = qmldirFile.absolutePath();
newLibraries->insert(libraryPath); newLibraries->insert(libraryPath);
if (lock) if (lock)
modelManager->updateLibraryInfo(libraryPath, LibraryInfo(qmldirParser), **lock); modelManager->updateLibraryInfo(libraryPath, LibraryInfo(qmldirParser), *lock);
else else
modelManager->updateLibraryInfo(libraryPath, LibraryInfo(qmldirParser)); modelManager->updateLibraryInfo(libraryPath, LibraryInfo(qmldirParser));
@@ -1379,7 +1384,7 @@ void ModelManagerInterface::updateImportPaths()
for (const Utils::FilePath &path : std::as_const(allApplicationDirectories)) { for (const Utils::FilePath &path : std::as_const(allApplicationDirectories)) {
allImportPaths.maybeInsert(path, Dialect::Qml); allImportPaths.maybeInsert(path, Dialect::Qml);
findNewQmlApplicationInPath(path, snapshot, this, &newLibraries); findNewQmlApplicationInPath(path, snapshot, this, &newLibraries, lock);
} }
for (const Utils::FilePath &qrcPath : generatedQrc(lock->m_projects.values())) for (const Utils::FilePath &qrcPath : generatedQrc(lock->m_projects.values()))
updateQrcFile(qrcPath); updateQrcFile(qrcPath);

View File

@@ -291,6 +291,13 @@ private:
private: private:
QList<Utils::FilePath> importPathsNames(const SyncedData &lockedData) const; QList<Utils::FilePath> importPathsNames(const SyncedData &lockedData) const;
static bool findNewQmlApplicationInPath(
const Utils::FilePath &path,
const Snapshot &snapshot,
ModelManagerInterface *modelManager,
QSet<Utils::FilePath> *newLibraries,
Utils::SynchronizedValue<ModelManagerInterface::SyncedData>::unique_lock &lock);
static void findNewLibraryImports(const Document::Ptr &doc, static void findNewLibraryImports(const Document::Ptr &doc,
const Snapshot &snapshot, const Snapshot &snapshot,
ModelManagerInterface *modelManager, ModelManagerInterface *modelManager,
@@ -310,7 +317,7 @@ private:
void updateLibraryInfo(const Utils::FilePath &path, void updateLibraryInfo(const Utils::FilePath &path,
const QmlJS::LibraryInfo &info, const QmlJS::LibraryInfo &info,
SyncedData &lockedData); Utils::SynchronizedValue<SyncedData>::unique_lock &lock);
}; };
} // namespace QmlJS } // namespace QmlJS