summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@qt.io>2024-02-07 21:32:20 +0100
committerMarc Mutz <marc.mutz@qt.io>2024-02-09 12:39:28 +0100
commitb28bad0b20719f72fb335a65f76382132e326ad0 (patch)
tree3329fb8b049caea75a32aea474ae90ccb9aaecc0
parent6675e8c942c2f9797d66269368c729c5556528c2 (diff)
Add fast-path in QLibraryStore::findOrCreate() for empty fileName
The LibraryMap can never contain an object whose fileName is empty. To see that, observe that the only insertion into LibraryMap is in findOrCreate() and that refuses to add such objects there. But if LibraryMap cannot contain such an object, and findOrCreate({}) is just an ugly way to get a default-constructed QLibraryPrivate (a new one for each call), then we don't need to lock the qt_library_mutex to produce one, and neither do we need to construct a mapName that we know we'll not find, anyway. So drag this case to before the mutex locking and the construction of mapName. It took me more coffee than I'm ready to admit to figure this out, so leave a comment for the next reader indicating that an empty fileName is actually a valid argument. To avoid repeating the new-expression, wrap it in a lambda, together with the ref() call. Move the remaining ref() call to where it's still needed. The final goal of this exercise is to get rid of the double-lookup in LibraryMap. Pick-to: 6.7 6.6 6.5 Change-Id: I781eafdb9516410d7a262ad27f52c38ad2742292 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r--src/corelib/plugin/qlibrary.cpp18
1 files changed, 14 insertions, 4 deletions
diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp
index 1f6d3e9019..ff1f4513ab 100644
--- a/src/corelib/plugin/qlibrary.cpp
+++ b/src/corelib/plugin/qlibrary.cpp
@@ -395,6 +395,15 @@ QLibraryStore *QLibraryStore::instance()
inline QLibraryPrivate *QLibraryStore::findOrCreate(const QString &fileName, const QString &version,
QLibrary::LoadHints loadHints)
{
+ auto lazyNewLib = [&] {
+ auto result = new QLibraryPrivate(fileName, version, loadHints);
+ result->libraryRefCount.ref();
+ return result;
+ };
+
+ if (fileName.isEmpty()) // request for empty d-pointer in QLibrary::setLoadHints();
+ return lazyNewLib(); // must return an independent (new) object
+
QMutexLocker locker(&qt_library_mutex);
QLibraryStore *data = instance();
@@ -404,17 +413,18 @@ inline QLibraryPrivate *QLibraryStore::findOrCreate(const QString &fileName, con
QLibraryPrivate *lib = nullptr;
if (Q_LIKELY(data)) {
lib = data->libraryMap.value(mapName);
- if (lib)
+ if (lib) {
+ lib->libraryRefCount.ref();
lib->mergeLoadHints(loadHints);
+ }
}
if (!lib)
- lib = new QLibraryPrivate(fileName, version, loadHints);
+ lib = lazyNewLib();
// track this library
- if (Q_LIKELY(data) && !fileName.isEmpty())
+ if (Q_LIKELY(data))
data->libraryMap.insert(mapName, lib);
- lib->libraryRefCount.ref();
return lib;
}