From 77eef3291782c967f17d703ca6a00477f7a76b11 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 10 Oct 2022 19:45:54 -0700 Subject: QLibrary: fix loading multiple versions of a library The libraryMap only stored the file path, so we couldn't load two versions of the same library as we'd find the other version already loaded. Change the map to index by file name and version (using a NUL as separator, since that can't appear in file names). [ChangeLog][QtCore][QLibrary] Fixed a bug that caused QLibrary to be unable to load two different versions of a library of a given name at the same time. Note that this is often inadviseable and loading the second library may cause a crash. Pick-to: 6.4 Change-Id: I12a088d1ae424825abd3fffd171ce3bb0590978d Reviewed-by: Qt CI Bot Reviewed-by: Fabian Kosmale --- src/corelib/plugin/qlibrary.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'src/corelib/plugin/qlibrary.cpp') diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp index 26b110b7de..abfb1e0df5 100644 --- a/src/corelib/plugin/qlibrary.cpp +++ b/src/corelib/plugin/qlibrary.cpp @@ -391,10 +391,12 @@ inline QLibraryPrivate *QLibraryStore::findOrCreate(const QString &fileName, con QMutexLocker locker(&qt_library_mutex); QLibraryStore *data = instance(); + QString mapName = version.isEmpty() ? fileName : fileName + u'\0' + version; + // check if this library is already loaded QLibraryPrivate *lib = nullptr; if (Q_LIKELY(data)) { - lib = data->libraryMap.value(fileName); + lib = data->libraryMap.value(mapName); if (lib) lib->mergeLoadHints(loadHints); } @@ -403,7 +405,7 @@ inline QLibraryPrivate *QLibraryStore::findOrCreate(const QString &fileName, con // track this library if (Q_LIKELY(data) && !fileName.isEmpty()) - data->libraryMap.insert(fileName, lib); + data->libraryMap.insert(mapName, lib); lib->libraryRefCount.ref(); return lib; @@ -423,9 +425,11 @@ inline void QLibraryStore::releaseLibrary(QLibraryPrivate *lib) Q_ASSERT(lib->libraryUnloadCount.loadRelaxed() == 0); if (Q_LIKELY(data) && !lib->fileName.isEmpty()) { - QLibraryPrivate *that = data->libraryMap.take(lib->fileName); - Q_ASSERT(lib == that); - Q_UNUSED(that); + qsizetype n = erase_if(data->libraryMap, [lib](LibraryMap::iterator it) { + return it.value() == lib; + }); + Q_ASSERT_X(n, "~QLibrary", "Did not find this library in the library map"); + Q_UNUSED(n); } delete lib; } -- cgit v1.2.3