summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/plugin/qlibrary.cpp14
-rw-r--r--tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp66
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");