diff options
-rw-r--r-- | src/corelib/plugin/qlibrary.cpp | 14 | ||||
-rw-r--r-- | tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp | 66 |
2 files changed, 75 insertions, 5 deletions
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; } diff --git a/tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp b/tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp index 2a494cb12d..018756e81e 100644 --- a/tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp +++ b/tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp @@ -96,6 +96,8 @@ private slots: void isLibrary(); void version_data(); void version(); + void loadTwoVersions(); + void setFileNameAndVersionTwice(); void setFileNameAndVersionAfterFailedLoad_data() { version_data(); } void setFileNameAndVersionAfterFailedLoad(); void errorString_data(); @@ -196,6 +198,70 @@ void tst_QLibrary::version() #endif } +void tst_QLibrary::loadTwoVersions() +{ +#if defined(Q_OS_ANDROID) || defined(Q_OS_WIN) + QSKIP("Versioned files are not generated for this OS, so this test is not applicable."); +#endif + + QLibrary lib1(directory + "/mylib", 1); + QLibrary lib2(directory + "/mylib", 2); + QVERIFY(!lib1.isLoaded()); + QVERIFY(!lib2.isLoaded()); + + // load the first one + QVERIFY(lib1.load()); + QVERIFY(lib1.isLoaded()); + + // let's see if we can load the second one too + QVERIFY(lib2.load()); + QVERIFY(lib2.isLoaded()); + + auto p1 = (VersionFunction)lib1.resolve("mylibversion"); + QVERIFY(p1); + + auto p2 = (VersionFunction)lib2.resolve("mylibversion"); + QVERIFY(p2); + + QCOMPARE_NE(p1(), p2()); + + lib2.unload(); + lib1.unload(); +} + +void tst_QLibrary::setFileNameAndVersionTwice() +{ +#if defined(Q_OS_ANDROID) || defined(Q_OS_WIN) + QSKIP("Versioned files are not generated for this OS, so this test is not applicable."); +#endif + + QLibrary library(directory + "/mylib", 1); + QVERIFY(library.load()); + QVERIFY(library.isLoaded()); + + auto p1 = (VersionFunction)library.resolve("mylibversion"); + QVERIFY(p1); + // don't .unload() + + library.setFileNameAndVersion(directory + "/mylib", 2); + QVERIFY(!library.isLoaded()); + QVERIFY(library.load()); + QVERIFY(library.isLoaded()); + + auto p2 = (VersionFunction)library.resolve("mylibversion"); + QVERIFY(p2); + QCOMPARE_NE(p1(), p2()); + + QVERIFY(library.unload()); + QVERIFY(!library.isLoaded()); + + // set back + library.setFileNameAndVersion(directory + "/mylib", 1); + QVERIFY(library.isLoaded()); + QVERIFY(library.unload()); + QVERIFY(!library.isLoaded()); +} + void tst_QLibrary::load_data() { QTest::addColumn<QString>("lib"); |