summaryrefslogtreecommitdiffstats
path: root/src/corelib/plugin/qpluginloader.cpp
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2023-03-25 13:32:26 -0400
committerThiago Macieira <thiago.macieira@intel.com>2023-04-05 00:29:16 -0700
commit2f226336a2aeb477b7ba339b6c3a63abb69746c3 (patch)
tree4926f1dfa51e355f13707d0e5de682b398326193 /src/corelib/plugin/qpluginloader.cpp
parenta74059f2bd353cdaa97cd71581059c0b88282a1b (diff)
QPluginLoader: don't instantiante multiple, identical instances
This can happen if the same project has two or more Q_IMPORT_PLUGIN macros in their source. And that can happen when converting from qmake- based builds to CMake, as qmake didn't generate a source file with the macro but CMake does. [ChangeLog][QtCore][QPluginLoader] staticInstances() will not call duplicated registrations of the same instantiation function, which can only happen as a result of duplicated Q_IMPORT_PLUGIN for the same plugin name. Fixes: QTBUG-102745 Pick-to: 6.2 6.5 Change-Id: Idd5e1bb52be047d7b4fffffd174fb9dd62d8583d Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/corelib/plugin/qpluginloader.cpp')
-rw-r--r--src/corelib/plugin/qpluginloader.cpp14
1 files changed, 13 insertions, 1 deletions
diff --git a/src/corelib/plugin/qpluginloader.cpp b/src/corelib/plugin/qpluginloader.cpp
index e07f1c2774b..b8052d55963 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);
}
/*!