Skip to content

Commit ab0b2ab

Browse files
committed
fix: synchronize plugin data phase loading
Changed plugin loading logic to ensure all plugins complete their module phase before any plugin starts the data phase. Previously, when a plugin reached ModuleEnd status, it would immediately proceed to LoadPluginTask for data loading. Now, the system waits until all plugins have finished their module phase (ModuleEnd, ModuleErr, or PluginEnd status) before starting data loading for any plugin. Key changes: 1. Added m_modulePhaseFinished flag to track module phase completion 2. Added allModulesFinished() method to check if all plugins have completed module phase 3. Added loadPluginData() method extracted from original loadPlugin() logic 4. Added onModulePhaseFinished() slot to handle transition to data phase 5. Modified loadPlugin() to check module phase completion before proceeding to data loading 6. Connected modulePhaseFinished signal to onModulePhaseFinished slot This ensures that plugins don't start their data loading (createData()) until all plugins have completed their module initialization, preventing potential race conditions and ensuring proper synchronization between plugins. Log: Fixed plugin loading synchronization issue Influence: 1. Test plugin loading with multiple plugins to ensure all complete module phase before data phase starts 2. Verify that plugins with ModuleEnd status wait for others before proceeding 3. Test edge cases where some plugins may have ModuleErr or PluginEnd status 4. Verify that the m_modulePhaseFinished flag is properly reset when needed 5. Test plugin loading performance to ensure no regression 6. Verify that hidden plugins (not visibleToApp) still follow the synchronization logic fix: 同步插件数据阶段加载 修改插件加载逻辑,确保所有插件完成模块阶段后再开始数据阶段。之前,当插件 达到 ModuleEnd 状态时,会立即进入 LoadPluginTask 进行数据加载。现在,系 统会等待所有插件完成模块阶段(ModuleEnd、ModuleErr 或 PluginEnd 状态)后 才开始任何插件的数据加载。 主要变更: 1. 添加 m_modulePhaseFinished 标志来跟踪模块阶段完成状态 2. 添加 allModulesFinished() 方法来检查所有插件是否已完成模块阶段 3. 添加 loadPluginData() 方法,从原始 loadPlugin() 逻辑中提取 4. 添加 onModulePhaseFinished() 槽函数来处理向数据阶段的过渡 5. 修改 loadPlugin() 以在进入数据加载前检查模块阶段完成状态 6. 连接 modulePhaseFinished 信号到 onModulePhaseFinished 槽 这确保了插件在所有插件完成模块初始化之前不会开始数据加载 (createData()),防止潜在的竞争条件并确保插件之间的正确同步。 Log: 修复插件加载同步问题 Influence: 1. 测试多插件加载,确保所有插件在数据阶段开始前完成模块阶段 2. 验证具有 ModuleEnd 状态的插件在继续之前会等待其他插件 3. 测试某些插件可能具有 ModuleErr 或 PluginEnd 状态的边缘情况 4. 验证 m_modulePhaseFinished 标志在需要时正确重置 5. 测试插件加载性能,确保没有回归问题 6. 验证隐藏插件(不可见)仍然遵循同步逻辑
1 parent 71b4faa commit ab0b2ab

2 files changed

Lines changed: 56 additions & 10 deletions

File tree

src/dde-control-center/pluginmanager.cpp

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -174,10 +174,12 @@ PluginManager::PluginManager(DccManager *parent)
174174
, m_rootModule(nullptr)
175175
, m_threadPool(nullptr)
176176
, m_isDeleting(false)
177+
, m_modulePhaseFinished(false)
177178
{
178179
qRegisterMetaType<PluginData>("PluginData");
179180
connect(this, &PluginManager::pluginEndStatusChanged, this, &PluginManager::loadPlugin);
180181
connect(this, &PluginManager::updatePluginStatus, this, &PluginManager::onUpdatePluginStatus);
182+
connect(this, &PluginManager::modulePhaseFinished, this, &PluginManager::onModulePhaseFinished);
181183
connect(m_manager, &DccManager::hideModuleChanged, this, &PluginManager::onHideModuleChanged);
182184
}
183185

@@ -322,6 +324,18 @@ bool PluginManager::preparePluginFactory(PluginData *plugin)
322324
return true;
323325
}
324326

327+
bool PluginManager::allModulesFinished() const
328+
{
329+
for (auto &&plugin : m_plugins) {
330+
uint status = plugin->status;
331+
bool moduleFinished = (status & ModuleEnd) || (status & ModuleErr) || (status & PluginEnd);
332+
if (!moduleFinished) {
333+
return false;
334+
}
335+
}
336+
return !m_plugins.isEmpty();
337+
}
338+
325339
QThreadPool *PluginManager::threadPool()
326340
{
327341
if (!m_threadPool) {
@@ -346,16 +360,12 @@ void PluginManager::loadPlugin(PluginData *plugin)
346360
} else if ((plugin->status & (DataEnd | MainObjLoad)) == DataEnd) {
347361
loadMain(plugin);
348362
} else if ((plugin->status & (ModuleEnd | DataBegin)) == ModuleEnd) {
349-
if (plugin->module) {
350-
disconnect(plugin->module, nullptr, this, nullptr);
351-
if (plugin->module->isVisibleToApp()) {
352-
threadPool()->start(new LoadPluginTask(plugin, this));
353-
} else {
354-
connect(plugin->module, &DccObject::visibleToAppChanged, this, &PluginManager::onVisibleToAppChanged);
355-
Q_EMIT updatePluginStatus(plugin, PluginEnd, QString());
356-
}
357-
} else {
358-
threadPool()->start(new LoadPluginTask(plugin, this));
363+
if (!m_modulePhaseFinished && allModulesFinished()) {
364+
Q_EMIT modulePhaseFinished();
365+
return;
366+
}
367+
if (m_modulePhaseFinished) {
368+
loadPluginData(plugin);
359369
}
360370
} else if ((plugin->status & (MetaDataEnd | ModuleLoad)) == MetaDataEnd) {
361371
if (!preparePluginFactory(plugin)) {
@@ -448,6 +458,24 @@ void PluginManager::loadModule(PluginData *plugin)
448458
}
449459
}
450460

461+
void PluginManager::loadPluginData(PluginData *plugin)
462+
{
463+
if (isDeleting()) {
464+
return;
465+
}
466+
if (plugin->module) {
467+
disconnect(plugin->module, nullptr, this, nullptr);
468+
if (plugin->module->isVisibleToApp()) {
469+
threadPool()->start(new LoadPluginTask(plugin, this));
470+
} else {
471+
connect(plugin->module, &DccObject::visibleToAppChanged, this, &PluginManager::onVisibleToAppChanged);
472+
Q_EMIT updatePluginStatus(plugin, PluginEnd, QString());
473+
}
474+
} else {
475+
threadPool()->start(new LoadPluginTask(plugin, this));
476+
}
477+
}
478+
451479
void PluginManager::loadMain(PluginData *plugin)
452480
{
453481
if (isDeleting()) {
@@ -591,6 +619,19 @@ void PluginManager::mainLoading()
591619
createMain(component);
592620
}
593621

622+
void PluginManager::onModulePhaseFinished()
623+
{
624+
if (isDeleting()) {
625+
return;
626+
}
627+
m_modulePhaseFinished = true;
628+
for (auto &&plugin : m_plugins) {
629+
if (plugin->status & ModuleEnd) {
630+
loadPlugin(plugin);
631+
}
632+
}
633+
}
634+
594635
void PluginManager::onHideModuleChanged(const QSet<QString> &hideModule)
595636
{
596637
for (auto &&plugin : m_plugins) {

src/dde-control-center/pluginmanager.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public Q_SLOTS:
3434
Q_SIGNALS:
3535
void addObject(DccObject *obj);
3636
void loadAllFinished();
37+
void modulePhaseFinished();
3738

3839
void pluginEndStatusChanged(PluginData *plugin);
3940
void updatePluginStatus(PluginData *plugin, uint status, const QString &log);
@@ -42,12 +43,14 @@ public Q_SLOTS:
4243
bool compareVersion(const QString &targetVersion, const QString &baseVersion);
4344
bool updatePluginType(PluginData *plugin);
4445
bool preparePluginFactory(PluginData *plugin);
46+
bool allModulesFinished() const;
4547
QThreadPool *threadPool();
4648

4749
private Q_SLOTS:
4850
void loadPlugin(PluginData *plugin);
4951
void loadMetaData(PluginData *plugin);
5052
void loadModule(PluginData *plugin);
53+
void loadPluginData(PluginData *plugin);
5154
void loadMain(PluginData *plugin);
5255
void createModule(QQmlComponent *component);
5356
void createMain(QQmlComponent *component);
@@ -56,6 +59,7 @@ private Q_SLOTS:
5659
void moduleLoading();
5760
void mainLoading();
5861

62+
void onModulePhaseFinished();
5963
void onHideModuleChanged(const QSet<QString> &hideModule);
6064
void onVisibleToAppChanged(bool visibleToApp);
6165
void onUpdatePluginStatus(PluginData *plugin, uint status, const QString &log);
@@ -66,6 +70,7 @@ private Q_SLOTS:
6670
DccObject *m_rootModule; // root module from MainWindow
6771
QThreadPool *m_threadPool;
6872
bool m_isDeleting;
73+
bool m_modulePhaseFinished;
6974
QQmlEngine *m_engine;
7075
};
7176

0 commit comments

Comments
 (0)