From 8ed47d961dc7e6f161030654d11cd330a542eadf Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Wed, 31 Aug 2011 15:17:30 +0200 Subject: Don't use QSettings to "cache" plugin information The main rationale of the cache was to examine the plugin's build-key before loading it. Now that the build-key has been removed, the cache has lost its usefulness. This is part of a larger push to not use QSettings for Qt specific settings or caches. See also: http://lists.qt.nokia.com/pipermail/qt5-feedback/2011-August/000892.html http://lists.qt.nokia.com/pipermail/qt5-feedback/2011-August/000960.html http://lists.qt.nokia.com/pipermail/qt5-feedback/2011-August/000907.html http://lists.qt.nokia.com/pipermail/qt5-feedback/2011-August/000904.html Change-Id: I96e84aa25983c8e06e027ff70cef109444c362a2 Reviewed-on: http://codereview.qt.nokia.com/3978 Reviewed-by: Qt Sanity Bot Reviewed-by: Lars Knoll --- src/corelib/kernel/qcoreapplication.cpp | 12 --- src/corelib/kernel/qcoreapplication_p.h | 1 - src/corelib/plugin/qfactoryloader.cpp | 57 ++++------- src/corelib/plugin/qlibrary.cpp | 165 +++++++++++--------------------- src/corelib/plugin/qlibrary_p.h | 3 +- src/corelib/plugin/qpluginloader.cpp | 16 ---- 6 files changed, 77 insertions(+), 177 deletions(-) diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 2458f9649e..6d8bf20b7c 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -266,18 +266,6 @@ bool QCoreApplicationPrivate::is_app_closing = false; // initialized in qcoreapplication and in qtextstream autotest when setlocale is called. Q_CORE_EXPORT bool qt_locale_initialized = false; - -/* - Create an instance of Trolltech.conf. This ensures that the settings will not - be thrown out of QSetting's cache for unused settings. - */ -Q_GLOBAL_STATIC_WITH_ARGS(QSettings, staticTrolltechConf, (QSettings::UserScope, QLatin1String("Trolltech"))) - -QSettings *QCoreApplicationPrivate::trolltechConf() -{ - return staticTrolltechConf(); -} - Q_CORE_EXPORT uint qGlobalPostedEventsCount() { QThreadData *currentThreadData = QThreadData::current(); diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h index 553e15f7db..8dff4ed80c 100644 --- a/src/corelib/kernel/qcoreapplication_p.h +++ b/src/corelib/kernel/qcoreapplication_p.h @@ -139,7 +139,6 @@ public: static uint attribs; static inline bool testAttribute(uint flag) { return attribs & (1 << flag); } static int app_compile_version; - static QSettings *trolltechConf(); }; QT_END_NAMESPACE diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp index c8831e5ae5..c175dcfe1b 100644 --- a/src/corelib/plugin/qfactoryloader.cpp +++ b/src/corelib/plugin/qfactoryloader.cpp @@ -45,7 +45,6 @@ #include "qfactoryinterface.h" #include "qmap.h" #include -#include #include #include "qmutex.h" #include "qplugin.h" @@ -107,7 +106,6 @@ void QFactoryLoader::update() #ifdef QT_SHARED Q_D(QFactoryLoader); QStringList paths = QCoreApplication::libraryPaths(); - QSettings settings(QSettings::UserScope, QLatin1String("Trolltech")); for (int i = 0; i < paths.count(); ++i) { const QString &pluginDir = paths.at(i); // Already loaded, skip it... @@ -127,7 +125,7 @@ void QFactoryLoader::update() qDebug() << "QFactoryLoader::QFactoryLoader() looking at" << fileName; } library = QLibraryPrivate::findOrCreate(QFileInfo(fileName).canonicalFilePath()); - if (!library->isPlugin(&settings)) { + if (!library->isPlugin()) { if (qt_debug_component()) { qDebug() << library->errorString; qDebug() << " not a plugin"; @@ -135,45 +133,26 @@ void QFactoryLoader::update() library->release(); continue; } - QString regkey = QString::fromLatin1("Qt Factory Cache %1.%2/%3:/%4") - .arg((QT_VERSION & 0xff0000) >> 16) - .arg((QT_VERSION & 0xff00) >> 8) - .arg(QLatin1String(d->iid)) - .arg(fileName); - QStringList reg, keys; - reg = settings.value(regkey).toStringList(); - if (reg.count() && library->lastModified == reg[0]) { - keys = reg; - keys.removeFirst(); - } else { - if (!library->loadPlugin()) { - if (qt_debug_component()) { - qDebug() << library->errorString; - qDebug() << " could not load"; - } - library->release(); - continue; - } - QObject *instance = library->instance(); - if (!instance) { - library->release(); - // ignore plugins that have a valid signature but cannot be loaded. - continue; + QStringList keys; + if (!library->loadPlugin()) { + if (qt_debug_component()) { + qDebug() << library->errorString; + qDebug() << " could not load"; } - QFactoryInterface *factory = qobject_cast(instance); - if (instance && factory && instance->qt_metacast(d->iid)) - keys = factory->keys(); - if (keys.isEmpty()) - library->unload(); - reg.clear(); - reg << library->lastModified; - reg += keys; - settings.setValue(regkey, reg); + library->release(); + continue; } - if (qt_debug_component()) { - qDebug() << "keys" << keys; + QObject *instance = library->instance(); + if (!instance) { + library->release(); + // ignore plugins that have a valid signature but cannot be loaded. + continue; } - + QFactoryInterface *factory = qobject_cast(instance); + if (instance && factory && instance->qt_metacast(d->iid)) + keys = factory->keys(); + if (keys.isEmpty()) + library->unload(); if (keys.isEmpty()) { library->release(); continue; diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp index 0a4ab77189..580dc37bd2 100644 --- a/src/corelib/plugin/qlibrary.cpp +++ b/src/corelib/plugin/qlibrary.cpp @@ -50,8 +50,6 @@ #include #include #include -#include -#include #include #ifdef Q_OS_MAC # include @@ -648,7 +646,7 @@ bool qt_get_verificationdata(QtPluginQueryVerificationDataFunction pfn, uint *qt return qt_parse_pattern(szData, qt_version, debug); } -bool QLibraryPrivate::isPlugin(QSettings *settings) +bool QLibraryPrivate::isPlugin() { errorString.clear(); if (pluginState != MightBeAPlugin) @@ -672,135 +670,88 @@ bool QLibraryPrivate::isPlugin(QSettings *settings) } #endif - QFileInfo fileinfo(fileName); - -#ifndef QT_NO_DATESTRING - lastModified = fileinfo.lastModified().toString(Qt::ISODate); -#endif - QString regkey = QString::fromLatin1("Qt Plugin Cache %1.%2.%3/%4") - .arg((QT_VERSION & 0xff0000) >> 16) - .arg((QT_VERSION & 0xff00) >> 8) - .arg(QLIBRARY_AS_DEBUG ? QLatin1String("debug") : QLatin1String("false")) - .arg(fileName); -#ifdef Q_WS_MAC - // On Mac, add the application arch to the reg key in order to - // cache plugin information separately for each arch. This prevents - // Qt from wrongly caching plugin load failures when the archs - // don't match. -#if defined(__x86_64__) - regkey += QLatin1String("-x86_64"); -#elif defined(__i386__) - regkey += QLatin1String("-i386"); -#elif defined(__ppc64__) - regkey += QLatin1String("-ppc64"); -#elif defined(__ppc__) - regkey += QLatin1String("-ppc"); -#endif -#endif // Q_WS_MAC - - QStringList reg; -#ifndef QT_NO_SETTINGS - if (!settings) { - settings = QCoreApplicationPrivate::trolltechConf(); - } - reg = settings->value(regkey).toStringList(); -#endif - if (reg.count() == 3 && lastModified == reg.at(2)) { - qt_version = reg.at(0).toUInt(0, 16); - debug = bool(reg.at(1).toInt()); - success = qt_version != 0; - } else { #if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(Q_OS_SYMBIAN) - if (!pHnd) { - // use unix shortcut to avoid loading the library - success = qt_unix_query(fileName, &qt_version, &debug, this); - } else + if (!pHnd) { + // use unix shortcut to avoid loading the library + success = qt_unix_query(fileName, &qt_version, &debug, this); + } else #endif - { - bool retryLoadLibrary = false; // Only used on Windows with MS compiler.(false in other cases) - do { - bool temporary_load = false; + { + bool retryLoadLibrary = false; // Only used on Windows with MS compiler.(false in other cases) + do { + bool temporary_load = false; #ifdef Q_OS_WIN - HMODULE hTempModule = 0; + HMODULE hTempModule = 0; #endif - if (!pHnd) { + if (!pHnd) { #ifdef Q_OS_WIN - DWORD dwFlags = (retryLoadLibrary) ? 0: DONT_RESOLVE_DLL_REFERENCES; - //avoid 'Bad Image' message box - UINT oldmode = SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX); - hTempModule = ::LoadLibraryEx((wchar_t*)QDir::toNativeSeparators(fileName).utf16(), 0, dwFlags); - SetErrorMode(oldmode); + DWORD dwFlags = (retryLoadLibrary) ? 0: DONT_RESOLVE_DLL_REFERENCES; + //avoid 'Bad Image' message box + UINT oldmode = SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX); + hTempModule = ::LoadLibraryEx((wchar_t*)QDir::toNativeSeparators(fileName).utf16(), 0, dwFlags); + SetErrorMode(oldmode); #else # if defined(Q_OS_SYMBIAN) - //Guard against accidentally trying to load non-plugin libraries by making sure the stub exists - if (fileinfo.exists()) + //Guard against accidentally trying to load non-plugin libraries by making sure the stub exists + if (fileinfo.exists()) # endif - temporary_load = load_sys(); + temporary_load = load_sys(); #endif - } + } #ifdef Q_OS_WIN - QtPluginQueryVerificationDataFunction qtPluginQueryVerificationDataFunction = hTempModule ? (QtPluginQueryVerificationDataFunction) + QtPluginQueryVerificationDataFunction qtPluginQueryVerificationDataFunction = hTempModule ? (QtPluginQueryVerificationDataFunction) #ifdef Q_OS_WINCE - ::GetProcAddress(hTempModule, L"qt_plugin_query_verification_data") + ::GetProcAddress(hTempModule, L"qt_plugin_query_verification_data") #else - ::GetProcAddress(hTempModule, "qt_plugin_query_verification_data") + ::GetProcAddress(hTempModule, "qt_plugin_query_verification_data") #endif - : (QtPluginQueryVerificationDataFunction) resolve("qt_plugin_query_verification_data"); + : (QtPluginQueryVerificationDataFunction) resolve("qt_plugin_query_verification_data"); #else - QtPluginQueryVerificationDataFunction qtPluginQueryVerificationDataFunction = NULL; + QtPluginQueryVerificationDataFunction qtPluginQueryVerificationDataFunction = NULL; # if defined(Q_OS_SYMBIAN) - if (temporary_load) { - qtPluginQueryVerificationDataFunction = (QtPluginQueryVerificationDataFunction) resolve("qt_plugin_query_verification_data"); - // If resolving with function name failed (i.e. not STDDLL), try resolving using known ordinal - if (!qtPluginQueryVerificationDataFunction) - qtPluginQueryVerificationDataFunction = (QtPluginQueryVerificationDataFunction) resolve("1"); - } -# else + if (temporary_load) { qtPluginQueryVerificationDataFunction = (QtPluginQueryVerificationDataFunction) resolve("qt_plugin_query_verification_data"); + // If resolving with function name failed (i.e. not STDDLL), try resolving using known ordinal + if (!qtPluginQueryVerificationDataFunction) + qtPluginQueryVerificationDataFunction = (QtPluginQueryVerificationDataFunction) resolve("1"); + } +# else + qtPluginQueryVerificationDataFunction = (QtPluginQueryVerificationDataFunction) resolve("qt_plugin_query_verification_data"); # endif #endif - bool exceptionThrown = false; - bool ret = qt_get_verificationdata(qtPluginQueryVerificationDataFunction, - &qt_version, &debug, &exceptionThrown); - if (!exceptionThrown) { - if (!ret) { - qt_version = 0; - if (temporary_load) - unload_sys(); - } else { - success = true; - } - retryLoadLibrary = false; + bool exceptionThrown = false; + bool ret = qt_get_verificationdata(qtPluginQueryVerificationDataFunction, + &qt_version, &debug, &exceptionThrown); + if (!exceptionThrown) { + if (!ret) { + qt_version = 0; + if (temporary_load) + unload_sys(); + } else { + success = true; } + retryLoadLibrary = false; + } #ifdef QT_USE_MS_STD_EXCEPTION - else { - // An exception was thrown when calling qt_plugin_query_verification_data(). - // This usually happens when plugin is compiled with the /clr compiler flag, - // & will only work if the dependencies are loaded & DLLMain() is called. - // LoadLibrary() will do this, try once with this & if it fails dont load. - retryLoadLibrary = !retryLoadLibrary; - } + else { + // An exception was thrown when calling qt_plugin_query_verification_data(). + // This usually happens when plugin is compiled with the /clr compiler flag, + // & will only work if the dependencies are loaded & DLLMain() is called. + // LoadLibrary() will do this, try once with this & if it fails dont load. + retryLoadLibrary = !retryLoadLibrary; + } #endif #ifdef Q_OS_WIN - if (hTempModule) { - BOOL ok = ::FreeLibrary(hTempModule); - if (ok) { - hTempModule = 0; - } - + if (hTempModule) { + BOOL ok = ::FreeLibrary(hTempModule); + if (ok) { + hTempModule = 0; } -#endif - } while(retryLoadLibrary); // Will be 'false' in all cases other than when an - // exception is thrown(will happen only when using a MS compiler) - } -#ifndef QT_NO_SETTINGS - QStringList queried; - queried << QString::number(qt_version,16) - << QString::number((int)debug) - << lastModified; - settings->setValue(regkey, queried); + } #endif + } while (retryLoadLibrary); // Will be 'false' in all cases other than when an + // exception is thrown(will happen only when using a MS compiler) } if (!success) { diff --git a/src/corelib/plugin/qlibrary_p.h b/src/corelib/plugin/qlibrary_p.h index 12d625050f..5559489767 100644 --- a/src/corelib/plugin/qlibrary_p.h +++ b/src/corelib/plugin/qlibrary_p.h @@ -68,7 +68,6 @@ QT_BEGIN_NAMESPACE bool qt_debug_component(); -class QSettings; class QLibraryPrivate { public: @@ -99,7 +98,7 @@ public: QString errorString; QLibrary::LoadHints loadHints; - bool isPlugin(QSettings *settings = 0); + bool isPlugin(); private: diff --git a/src/corelib/plugin/qpluginloader.cpp b/src/corelib/plugin/qpluginloader.cpp index bbb64e42e7..591e36e20a 100644 --- a/src/corelib/plugin/qpluginloader.cpp +++ b/src/corelib/plugin/qpluginloader.cpp @@ -98,22 +98,6 @@ QT_BEGIN_NAMESPACE every instance has called unload(). Right before the unloading happen, the root component will also be deleted. - In order to speed up loading and validation of plugins, some of - the information that is collected during loading is cached in - persistent memory (through QSettings). For instance, the result - of a load operation (e.g. succeeded or failed) is stored in the - cache, so that subsequent load operations don't try to load an - invalid plugin. However, if the "last modified" timestamp of - a plugin has changed, the plugin's cache entry is invalidated - and the plugin is reloaded regardless of the values in the cache - entry. The cache entry is then updated with the new result of the - load operation. - - This also means that the timestamp must be updated each time the - plugin or any dependent resources (such as a shared library) is - updated, since the dependent resources might influence the result - of loading a plugin. - See \l{How to Create Qt Plugins} for more information about how to make your application extensible through plugins. -- cgit v1.2.3