Don't use QSettings to "cache" plugin information
authorBradley T. Hughes <bradley.hughes@nokia.com>
Wed, 31 Aug 2011 13:17:30 +0000 (15:17 +0200)
committerQt by Nokia <qt-info@nokia.com>
Mon, 5 Sep 2011 11:31:14 +0000 (13:31 +0200)
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 <qt_sanity_bot@ovi.com>
Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
src/corelib/kernel/qcoreapplication.cpp
src/corelib/kernel/qcoreapplication_p.h
src/corelib/plugin/qfactoryloader.cpp
src/corelib/plugin/qlibrary.cpp
src/corelib/plugin/qlibrary_p.h
src/corelib/plugin/qpluginloader.cpp

index 2458f96..6d8bf20 100644 (file)
@@ -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();
index 553e15f..8dff4ed 100644 (file)
@@ -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
index c8831e5..c175dcf 100644 (file)
@@ -45,7 +45,6 @@
 #include "qfactoryinterface.h"
 #include "qmap.h"
 #include <qdir.h>
-#include <qsettings.h>
 #include <qdebug.h>
 #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<QFactoryInterface*>(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<QFactoryInterface*>(instance);
+            if (instance && factory && instance->qt_metacast(d->iid))
+                keys = factory->keys();
+            if (keys.isEmpty())
+                library->unload();
             if (keys.isEmpty()) {
                 library->release();
                 continue;
index 0a4ab77..580dc37 100644 (file)
@@ -50,8 +50,6 @@
 #include <qfileinfo.h>
 #include <qmutex.h>
 #include <qmap.h>
-#include <qsettings.h>
-#include <qdatetime.h>
 #include <private/qcoreapplication_p.h>
 #ifdef Q_OS_MAC
 #  include <private/qcore_mac_p.h>
@@ -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) {
index 12d6250..5559489 100644 (file)
@@ -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:
index bbb64e4..591e36e 100644 (file)
@@ -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.