ExtensionSystem: Use dependency order when loading plugins at runtime

And also run IPlugin::delayedInitialize when loading plugins at runtime

Amends 32914fe66b

Change-Id: Ib2a6c4c6122dd1ac915f7755b0d7ea232fa635e8
Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io>
This commit is contained in:
Eike Ziller
2023-11-13 16:17:16 +01:00
parent 9e00e1d6a0
commit bb27b3b02a
4 changed files with 32 additions and 8 deletions

View File

@@ -322,11 +322,9 @@ void PluginManager::loadPlugins()
d->loadPlugins(); d->loadPlugins();
} }
void PluginManager::loadPlugin(PluginSpec *spec) void PluginManager::loadPluginsAtRuntime(const QSet<PluginSpec *> &plugins)
{ {
d->loadPlugin(spec, PluginSpec::Loaded); d->loadPluginsAtRuntime(plugins);
d->loadPlugin(spec, PluginSpec::Initialized);
d->loadPlugin(spec, PluginSpec::Running);
} }
/*! /*!
@@ -1389,6 +1387,32 @@ void PluginManagerPrivate::loadPlugins()
delayedInitializeTimer.start(); delayedInitializeTimer.start();
} }
void PluginManagerPrivate::loadPluginsAtRuntime(const QSet<PluginSpec *> &plugins)
{
QTC_CHECK(allOf(plugins, [](PluginSpec *spec) { return spec->isSoftLoadable(); }));
// load the plugins ordered by dependency
const QList<PluginSpec *> queue = filtered(loadQueue(), [&plugins](PluginSpec *spec) {
return plugins.contains(spec);
});
std::queue<PluginSpec *> localDelayedInitializeQueue;
for (PluginSpec *spec : queue)
loadPlugin(spec, PluginSpec::Loaded);
for (PluginSpec *spec : queue)
loadPlugin(spec, PluginSpec::Initialized);
Utils::reverseForeach(queue,
[this](PluginSpec *spec) { loadPlugin(spec, PluginSpec::Running); });
Utils::reverseForeach(queue, [](PluginSpec *spec) {
if (spec->state() == PluginSpec::Running) {
const bool delay = spec->d->delayedInitialize();
if (delay)
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
} else {
// Plugin initialization failed, so cleanup after it
spec->d->kill();
}
});
}
/*! /*!
\internal \internal
*/ */

View File

@@ -68,7 +68,7 @@ public:
// Plugin operations // Plugin operations
static QVector<PluginSpec *> loadQueue(); static QVector<PluginSpec *> loadQueue();
static void loadPlugins(); static void loadPlugins();
static void loadPlugin(PluginSpec *); static void loadPluginsAtRuntime(const QSet<PluginSpec *> &plugins);
static QStringList pluginPaths(); static QStringList pluginPaths();
static void setPluginPaths(const QStringList &paths); static void setPluginPaths(const QStringList &paths);
static QString pluginIID(); static QString pluginIID();

View File

@@ -51,6 +51,7 @@ public:
// Plugin operations // Plugin operations
void checkForProblematicPlugins(); void checkForProblematicPlugins();
void loadPlugins(); void loadPlugins();
void loadPluginsAtRuntime(const QSet<PluginSpec *> &plugins);
void shutdown(); void shutdown();
void setPluginPaths(const QStringList &paths); void setPluginPaths(const QStringList &paths);
const QVector<ExtensionSystem::PluginSpec *> loadQueue(); const QVector<ExtensionSystem::PluginSpec *> loadQueue();

View File

@@ -88,10 +88,9 @@ void PluginDialog::closeDialog()
{ {
PluginManager::writeSettings(); PluginManager::writeSettings();
for (PluginSpec *plugin : m_softLoad) { PluginManager::loadPluginsAtRuntime(m_softLoad);
PluginManager::loadPlugin(plugin); for (PluginSpec *plugin : std::as_const(m_softLoad))
CorePlugin::loadMimeFromPlugin(plugin); CorePlugin::loadMimeFromPlugin(plugin);
}
if (m_isRestartRequired) { if (m_isRestartRequired) {
RestartDialog restartDialog(ICore::dialogParent(), RestartDialog restartDialog(ICore::dialogParent(),