summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/plugin/qpluginloader.cpp14
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp26
2 files changed, 32 insertions, 8 deletions
diff --git a/src/corelib/plugin/qpluginloader.cpp b/src/corelib/plugin/qpluginloader.cpp
index e07f1c2774..b8052d5596 100644
--- a/src/corelib/plugin/qpluginloader.cpp
+++ b/src/corelib/plugin/qpluginloader.cpp
@@ -379,7 +379,19 @@ Q_GLOBAL_STATIC(StaticPluginList, staticPluginList)
*/
void Q_CORE_EXPORT qRegisterStaticPluginFunction(QStaticPlugin plugin)
{
- staticPluginList()->append(plugin);
+ // using operator* because we shouldn't be registering plugins while
+ // unloading the application!
+ StaticPluginList &plugins = *staticPluginList;
+
+ // insert the plugin in the list, sorted by address, so we can detect
+ // duplicate registrations
+ auto comparator = [=](const QStaticPlugin &p1, const QStaticPlugin &p2) {
+ using Less = std::less<decltype(plugin.instance)>;
+ return Less{}(p1.instance, p2.instance);
+ };
+ auto pos = std::lower_bound(plugins.constBegin(), plugins.constEnd(), plugin, comparator);
+ if (pos == plugins.constEnd() || pos->instance != plugin.instance)
+ plugins.insert(pos, plugin);
}
/*!
diff --git a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp
index adea6af515..e6d1785dca 100644
--- a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp
+++ b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp
@@ -206,6 +206,7 @@ private slots:
void preloadedPlugin_data();
void preloadedPlugin();
void staticPlugins();
+ void reregisteredStaticPlugins();
};
Q_IMPORT_PLUGIN(StaticPlugin)
@@ -1080,19 +1081,18 @@ void tst_QPluginLoader::staticPlugins()
const QObjectList instances = QPluginLoader::staticInstances();
QVERIFY(instances.size());
- bool found = false;
- for (QObject *obj : instances) {
- found = obj->metaObject()->className() == QLatin1String("StaticPlugin");
- if (found)
- break;
- }
- QVERIFY(found);
+ // ensure the our plugin only shows up once
+ int foundCount = std::count_if(instances.begin(), instances.end(), [](QObject *obj) {
+ return obj->metaObject()->className() == QLatin1String("StaticPlugin");
+ });
+ QCOMPARE(foundCount, 1);
const auto plugins = QPluginLoader::staticPlugins();
QCOMPARE(plugins.size(), instances.size());
// find the metadata
QJsonObject metaData;
+ bool found = false;
for (const auto &p : plugins) {
metaData = p.metaData();
found = metaData.value("className").toString() == QLatin1String("StaticPlugin");
@@ -1108,6 +1108,18 @@ void tst_QPluginLoader::staticPlugins()
QCOMPARE(metaData.value("URI").toString(), "qt.test.pluginloader.staticplugin");
}
+void tst_QPluginLoader::reregisteredStaticPlugins()
+{
+ // the Q_IMPORT_PLUGIN macro will have already done this
+ qRegisterStaticPluginFunction(qt_static_plugin_StaticPlugin());
+ staticPlugins();
+ if (QTest::currentTestFailed())
+ return;
+
+ qRegisterStaticPluginFunction(qt_static_plugin_StaticPlugin());
+ staticPlugins();
+}
+
QTEST_MAIN(tst_QPluginLoader)
#include "tst_qpluginloader.moc"