summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2021-11-09 09:00:06 -0800
committerThiago Macieira <thiago.macieira@intel.com>2022-01-20 23:53:48 +0000
commit7bc788ed0c6b94320fd14a4c075a50d66f02f9ff (patch)
treee55b1a38b156016d140c267b9e928effd1021e85 /src
parentc062fed4275c07e5c7a1a18d0779144519bec799 (diff)
QFactoryLoader: separate the updating of each plugin path
I'm going to need to call this with a different path. Pick-to: 6.3 Change-Id: I5e52dc5b093c43a3b678fffd16b5ef59376498ee Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/plugin/qfactoryloader.cpp189
1 files changed, 97 insertions, 92 deletions
diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp
index 79423251a4..19d858bf8d 100644
--- a/src/corelib/plugin/qfactoryloader.cpp
+++ b/src/corelib/plugin/qfactoryloader.cpp
@@ -136,11 +136,13 @@ public:
#if QT_CONFIG(library)
~QFactoryLoaderPrivate();
mutable QMutex mutex;
+ QDuplicateTracker<QString> loadedPaths;
QList<QLibraryPrivate*> libraryList;
QMap<QString,QLibraryPrivate*> keyMap;
QString suffix;
Qt::CaseSensitivity cs;
- QDuplicateTracker<QString> loadedPaths;
+
+ void updateSinglePath(const QString &pluginDir);
#endif
};
@@ -159,117 +161,120 @@ QFactoryLoaderPrivate::~QFactoryLoaderPrivate()
library->release();
}
-void QFactoryLoader::update()
+inline void QFactoryLoaderPrivate::updateSinglePath(const QString &path)
{
-#ifdef QT_SHARED
- Q_D(QFactoryLoader);
- QStringList paths = QCoreApplication::libraryPaths();
- for (int i = 0; i < paths.count(); ++i) {
- const QString &pluginDir = paths.at(i);
- // Already loaded, skip it...
- if (d->loadedPaths.hasSeen(pluginDir))
- continue;
+ // If we've already loaded, skip it...
+ if (loadedPaths.hasSeen(path))
+ return;
-#ifdef Q_OS_ANDROID
- QString path = pluginDir;
-#else
- QString path = pluginDir + d->suffix;
-#endif
-
- qCDebug(lcFactoryLoader) << "checking directory path" << path << "...";
+ qCDebug(lcFactoryLoader) << "checking directory path" << path << "...";
- if (!QDir(path).exists(QLatin1String(".")))
- continue;
+ if (!QDir(path).exists(QLatin1String(".")))
+ return;
- QStringList plugins = QDir(path).entryList(
+ QStringList plugins = QDir(path).entryList(
#if defined(Q_OS_WIN)
- QStringList(QStringLiteral("*.dll")),
+ QStringList(QStringLiteral("*.dll")),
#elif defined(Q_OS_ANDROID)
- QStringList(QLatin1String("libplugins_%1_*.so").arg(d->suffix)),
+ QStringList(QLatin1String("libplugins_%1_*.so").arg(suffix)),
#endif
- QDir::Files);
- QLibraryPrivate *library = nullptr;
-
- for (int j = 0; j < plugins.count(); ++j) {
- QString fileName = QDir::cleanPath(path + QLatin1Char('/') + plugins.at(j));
+ QDir::Files);
+ for (int j = 0; j < plugins.count(); ++j) {
+ QString fileName = QDir::cleanPath(path + QLatin1Char('/') + plugins.at(j));
#ifdef Q_OS_MAC
- const bool isDebugPlugin = fileName.endsWith(QLatin1String("_debug.dylib"));
- const bool isDebugLibrary =
- #ifdef QT_DEBUG
- true;
- #else
- false;
- #endif
-
- // Skip mismatching plugins so that we don't end up loading both debug and release
- // versions of the same Qt libraries (due to the plugin's dependencies).
- if (isDebugPlugin != isDebugLibrary)
- continue;
+ const bool isDebugPlugin = fileName.endsWith(QLatin1String("_debug.dylib"));
+ const bool isDebugLibrary =
+ #ifdef QT_DEBUG
+ true;
+ #else
+ false;
+ #endif
+
+ // Skip mismatching plugins so that we don't end up loading both debug and release
+ // versions of the same Qt libraries (due to the plugin's dependencies).
+ if (isDebugPlugin != isDebugLibrary)
+ continue;
#elif defined(Q_PROCESSOR_X86)
- if (fileName.endsWith(QLatin1String(".avx2")) || fileName.endsWith(QLatin1String(".avx512"))) {
- // ignore AVX2-optimized file, we'll do a bait-and-switch to it later
- continue;
- }
+ if (fileName.endsWith(QLatin1String(".avx2")) || fileName.endsWith(QLatin1String(".avx512"))) {
+ // ignore AVX2-optimized file, we'll do a bait-and-switch to it later
+ continue;
+ }
#endif
- qCDebug(lcFactoryLoader) << "looking at" << fileName;
+ qCDebug(lcFactoryLoader) << "looking at" << fileName;
- Q_TRACE(QFactoryLoader_update, fileName);
+ Q_TRACE(QFactoryLoader_update, fileName);
- library = QLibraryPrivate::findOrCreate(QFileInfo(fileName).canonicalFilePath());
- if (!library->isPlugin()) {
- qCDebug(lcFactoryLoader) << library->errorString << Qt::endl
- << " not a plugin";
- library->release();
- continue;
- }
-
- QStringList keys;
- bool metaDataOk = false;
+ QLibraryPrivate *library = QLibraryPrivate::findOrCreate(QFileInfo(fileName).canonicalFilePath());
+ if (!library->isPlugin()) {
+ qCDebug(lcFactoryLoader) << library->errorString << Qt::endl
+ << " not a plugin";
+ library->release();
+ continue;
+ }
- QString iid = library->metaData.value(QtPluginMetaDataKeys::IID).toString();
- if (iid == QLatin1String(d->iid.constData(), d->iid.size())) {
- QCborMap object = library->metaData.value(QtPluginMetaDataKeys::MetaData).toMap();
- metaDataOk = true;
+ QStringList keys;
+ bool metaDataOk = false;
- QCborArray k = object.value(QLatin1String("Keys")).toArray();
- for (int i = 0; i < k.size(); ++i)
- keys += d->cs ? k.at(i).toString() : k.at(i).toString().toLower();
- }
- qCDebug(lcFactoryLoader) << "Got keys from plugin meta data" << keys;
+ QString iid = library->metaData.value(QtPluginMetaDataKeys::IID).toString();
+ if (iid == QLatin1String(this->iid.constData(), this->iid.size())) {
+ QCborMap object = library->metaData.value(QtPluginMetaDataKeys::MetaData).toMap();
+ metaDataOk = true;
+ QCborArray k = object.value(QLatin1String("Keys")).toArray();
+ for (int i = 0; i < k.size(); ++i)
+ keys += cs ? k.at(i).toString() : k.at(i).toString().toLower();
+ }
+ qCDebug(lcFactoryLoader) << "Got keys from plugin meta data" << keys;
- if (!metaDataOk) {
- library->release();
- continue;
- }
+ if (!metaDataOk) {
+ library->release();
+ continue;
+ }
- int keyUsageCount = 0;
- for (int k = 0; k < keys.count(); ++k) {
- // first come first serve, unless the first
- // library was built with a future Qt version,
- // whereas the new one has a Qt version that fits
- // better
- constexpr int QtVersionNoPatch = QT_VERSION_CHECK(QT_VERSION_MAJOR, QT_VERSION_MINOR, 0);
- const QString &key = keys.at(k);
- QLibraryPrivate *previous = d->keyMap.value(key);
- int prev_qt_version = 0;
- if (previous)
- prev_qt_version = int(previous->metaData.value(QtPluginMetaDataKeys::QtVersion).toInteger());
- int qt_version = int(library->metaData.value(QtPluginMetaDataKeys::QtVersion).toInteger());
- if (!previous || (prev_qt_version > QtVersionNoPatch && qt_version <= QtVersionNoPatch)) {
- d->keyMap[key] = library;
- ++keyUsageCount;
- }
- }
- if (keyUsageCount || keys.isEmpty()) {
- library->setLoadHints(QLibrary::PreventUnloadHint); // once loaded, don't unload
- QMutexLocker locker(&d->mutex);
- d->libraryList += library;
- } else {
- library->release();
+ int keyUsageCount = 0;
+ for (int k = 0; k < keys.count(); ++k) {
+ // first come first serve, unless the first
+ // library was built with a future Qt version,
+ // whereas the new one has a Qt version that fits
+ // better
+ constexpr int QtVersionNoPatch = QT_VERSION_CHECK(QT_VERSION_MAJOR, QT_VERSION_MINOR, 0);
+ const QString &key = keys.at(k);
+ QLibraryPrivate *previous = keyMap.value(key);
+ int prev_qt_version = 0;
+ if (previous)
+ prev_qt_version = int(previous->metaData.value(QtPluginMetaDataKeys::QtVersion).toInteger());
+ int qt_version = int(library->metaData.value(QtPluginMetaDataKeys::QtVersion).toInteger());
+ if (!previous || (prev_qt_version > QtVersionNoPatch && qt_version <= QtVersionNoPatch)) {
+ keyMap[key] = library;
+ ++keyUsageCount;
}
}
+ if (keyUsageCount || keys.isEmpty()) {
+ library->setLoadHints(QLibrary::PreventUnloadHint); // once loaded, don't unload
+ QMutexLocker locker(&mutex);
+ libraryList += library;
+ } else {
+ library->release();
+ }
+ };
+}
+
+void QFactoryLoader::update()
+{
+#ifdef QT_SHARED
+ Q_D(QFactoryLoader);
+
+ QStringList paths = QCoreApplication::libraryPaths();
+ for (int i = 0; i < paths.count(); ++i) {
+ const QString &pluginDir = paths.at(i);
+#ifdef Q_OS_ANDROID
+ QString path = pluginDir;
+#else
+ QString path = pluginDir + d->suffix;
+#endif
+
+ d->updateSinglePath(path);
}
#else
Q_D(QFactoryLoader);