diff options
| author | Thiago Macieira <thiago.macieira@intel.com> | 2023-03-25 13:32:26 -0400 |
|---|---|---|
| committer | Thiago Macieira <thiago.macieira@intel.com> | 2023-04-05 00:29:16 -0700 |
| commit | 2f226336a2aeb477b7ba339b6c3a63abb69746c3 (patch) | |
| tree | 4926f1dfa51e355f13707d0e5de682b398326193 /src/corelib/plugin/qpluginloader.cpp | |
| parent | a74059f2bd353cdaa97cd71581059c0b88282a1b (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.cpp | 14 |
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); } /*! |
