Skip to content

Conversation

@Dami-star
Copy link

…lifecycle management

Problem:

  • Single-threaded design with weak state machine (Invalid -> Succeed/Failed)
  • No proper handling of object destruction during initialization
  • Signal emissions in worker thread context (incorrect thread context)
  • Fragile destructor unable to handle all cleanup scenarios

Solution:

  1. Introduce Data layer separation (TreelandUserConfigData + TreelandUserConfig)

    • Clear separation between internal data management and public API
    • Enables safer object lifecycle management
  2. Enhance state machine (3-state -> 5-state model)

    • Add Initializing and Destroyed states
    • Use atomic CAS operations for thread-safe state transitions
    • States: Invalid -> Initializing -> (Succeed | Failed | Destroyed)
  3. Improve async initialization and cleanup

    • Use QPointer for safe backref checks (prevent use-after-free)
    • Support 4 destruction paths: normal/failed/quick/mid-initialization
    • Atomic state transitions with proper signal emission guards
  4. Separate thread responsibilities

    • updateValue(): Worker thread reads config values
    • updateProperty(): Main thread updates properties and emits signals
    • Use QMetaObject::invokeMethod for correct thread context

Improvements:

  • Thread safety: Complete atomic operations coverage
  • Memory safety: QPointer guards prevent dangling pointers
  • Code clarity: Layered architecture with clear responsibilities
  • Backward compatibility: API unchanged

@deepin-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: Dami-star

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

deepin-ci-robot added a commit to linuxdeepin/dtk6core that referenced this pull request Jan 7, 2026
Synchronize source files from linuxdeepin/dtkcore.

Source-pull-request: linuxdeepin/dtkcore#531
@wineee wineee requested a review from Copilot January 7, 2026 09:35
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the DConfig C++ wrapper class generation tool (dconfig2cpp) to improve thread safety and lifecycle management. The refactor introduces a data layer separation pattern, enhances the state machine from 3 states to 5 states, and implements atomic operations for thread-safe state transitions.

Key changes:

  • Introduces a Data class (TreelandUserConfigData) to separate internal data management from the public API (TreelandUserConfig)
  • Expands state machine from Invalid/Succeed/Failed to Invalid/Initializing/Succeed/Failed/Destroyed with atomic CAS operations
  • Separates thread responsibilities: updateValue() in worker thread, updateProperty() in main thread with QMetaObject::invokeMethod for proper thread context

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Member

@zccrs zccrs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

还没有看完

deepin-ci-robot added a commit to linuxdeepin/dtk6core that referenced this pull request Jan 13, 2026
Synchronize source files from linuxdeepin/dtkcore.

Source-pull-request: linuxdeepin/dtkcore#531
deepin-ci-robot added a commit to linuxdeepin/dtk6core that referenced this pull request Jan 13, 2026
Synchronize source files from linuxdeepin/dtkcore.

Source-pull-request: linuxdeepin/dtkcore#531
@Dami-star Dami-star requested a review from zccrs January 14, 2026 01:52
deepin-ci-robot added a commit to linuxdeepin/dtk6core that referenced this pull request Jan 14, 2026
Synchronize source files from linuxdeepin/dtkcore.

Source-pull-request: linuxdeepin/dtkcore#531
@zccrs zccrs requested a review from Copilot January 14, 2026 06:03
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

m_data->deleteLater();
}
} else if (oldStatus == static_cast<int>(Data::Status::Failed) || oldStatus == static_cast<int>(Data::Status::Invalid)) {
m_data->deleteLater();
Copy link

Copilot AI Jan 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The destructor has a potential memory leak scenario. When oldStatus is Initializing, m_data is not deleted. This can occur if the destructor is called while initialization is still in progress on the worker thread. The code should handle the Initializing state by marking it as Destroyed and allowing the worker thread to clean up, or explicitly delete m_data.

Suggested change
m_data->deleteLater();
m_data->deleteLater();
} else if (oldStatus == static_cast<int>(Data::Status::Initializing)) {
m_data->deleteLater();

Copilot uses AI. Check for mistakes.
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

当 oldStatus 为 Initializing 时,我们不会在此处删除, 若在此处删除会导致空指针。工作线程将检测到 Destroyed 状态并自行清理 m_data。

deepin-ci-robot added a commit to linuxdeepin/dtk6core that referenced this pull request Jan 14, 2026
Synchronize source files from linuxdeepin/dtkcore.

Source-pull-request: linuxdeepin/dtkcore#531
deepin-ci-robot added a commit to linuxdeepin/dtk6core that referenced this pull request Jan 15, 2026
Synchronize source files from linuxdeepin/dtkcore.

Source-pull-request: linuxdeepin/dtkcore#531
deepin-ci-robot added a commit to linuxdeepin/dtk6core that referenced this pull request Jan 15, 2026
Synchronize source files from linuxdeepin/dtkcore.

Source-pull-request: linuxdeepin/dtkcore#531
deepin-ci-robot added a commit to linuxdeepin/dtk6core that referenced this pull request Jan 15, 2026
Synchronize source files from linuxdeepin/dtkcore.

Source-pull-request: linuxdeepin/dtkcore#531
deepin-ci-robot added a commit to linuxdeepin/dtk6core that referenced this pull request Jan 16, 2026
Synchronize source files from linuxdeepin/dtkcore.

Source-pull-request: linuxdeepin/dtkcore#531
deepin-ci-robot added a commit to linuxdeepin/dtk6core that referenced this pull request Jan 16, 2026
Synchronize source files from linuxdeepin/dtkcore.

Source-pull-request: linuxdeepin/dtkcore#531
deepin-ci-robot added a commit to linuxdeepin/dtk6core that referenced this pull request Jan 16, 2026
Synchronize source files from linuxdeepin/dtkcore.

Source-pull-request: linuxdeepin/dtkcore#531
delete worker;
worker = nullptr;

auto data = safeData;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个赋值有啥必要吗

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

之前删的一块逻辑 等下删除了

if (!data->m_status.testAndSetOrdered(static_cast<int>(Data::Status::Invalid),
static_cast<int>(Data::Status::Initializing))) {
if (data->m_status.loadRelaxed() == static_cast<int>(Data::Status::Destroyed)) {
QMetaObject::invokeMethod(data, [data]() { delete data; }, Qt::QueuedConnection);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

data对象的生命管理是这样的:在状态变为 Initializing 之前,data被dconfig_org_deepin_dtk_preference对象负责销毁,在 Initializing 状态或 Succeeded 状态下,跟随config对象销毁。

所以这里直接返回就行,不用管 data 对象。

worker = nullptr;

auto data = safeData;
if (!data) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不需要做这个判断,在判断 m_status 之后,可以对data对象做断言。

…lifecycle management

Problem:
- Single-threaded design with weak state machine (Invalid -> Succeed/Failed)
- No proper handling of object destruction during initialization
- Signal emissions in worker thread context (incorrect thread context)
- Fragile destructor unable to handle all cleanup scenarios

Solution:
1. Introduce Data layer separation (TreelandUserConfigData + TreelandUserConfig)
   - Clear separation between internal data management and public API
   - Enables safer object lifecycle management

2. Enhance state machine (3-state -> 5-state model)
   - Add Initializing and Destroyed states
   - Use atomic CAS operations for thread-safe state transitions
   - States: Invalid -> Initializing -> (Succeed | Failed | Destroyed)

3. Improve async initialization and cleanup
   - Use QPointer for safe backref checks (prevent use-after-free)
   - Support 4 destruction paths: normal/failed/quick/mid-initialization
   - Atomic state transitions with proper signal emission guards

4. Separate thread responsibilities
   - updateValue(): Worker thread reads config values
   - updateProperty(): Main thread updates properties and emits signals
   - Use QMetaObject::invokeMethod for correct thread context

Improvements:
- Thread safety: Complete atomic operations coverage
- Memory safety: QPointer guards prevent dangling pointers
- Code clarity: Layered architecture with clear responsibilities
- Backward compatibility: API unchanged
deepin-ci-robot added a commit to linuxdeepin/dtk6core that referenced this pull request Jan 16, 2026
Synchronize source files from linuxdeepin/dtkcore.

Source-pull-request: linuxdeepin/dtkcore#531
@deepin-ci-robot
Copy link
Contributor

deepin pr auto review

代码审查报告

总体评价

这段代码是自动生成的 DConfig 配置管理类,主要改进了线程安全性和对象生命周期管理。代码整体结构清晰,使用了现代 C++ 和 Qt 特性,但存在一些可以优化的地方。

语法与逻辑

优点

  1. 线程安全改进:使用了原子操作(QAtomicPointer, QAtomicInteger)和 CAS(Compare-And-Swap)操作来管理状态转换
  2. 对象生命周期管理:通过 Data 类和 QPointer 实现了更安全的对象生命周期管理
  3. 信号连接优化:使用 QPointer 保护 Data 对象生命周期,避免悬空指针

问题与建议

  1. 构造函数中的线程检查
Q_ASSERT(QThread::currentThread() != thread);
  • 建议:在 Release 模式下也应该有相应的运行时检查,而不仅仅是 Debug 模式的断言
  1. 事件处理中的断言
bool event(QEvent *e) override {
    if (e->type() == QEvent::ThreadChange) {
        Q_ASSERT_X(false, "dconfig_dconf-example_meta", "Moving ... is forbidden!");
    }
    return QObject::event(e);
}
  • 问题:Release 模式下这个断言不会生效
  • 建议:改为运行时错误处理:
if (e->type() == QEvent::ThreadChange) {
    qCritical() << "Moving dconfig object to another thread is forbidden!";
    return false;
}

代码质量

优点

  1. 代码组织:将实现细节封装在 Data 类中,提高了封装性
  2. 注释清晰:关键逻辑都有注释说明
  3. 一致性:所有生成的类遵循相同的模式和命名约定

问题与建议

  1. 重复代码:多个 updateProperty 方法有大量重复代码
  • 建议:可以考虑使用模板或宏来减少重复代码
  1. 魔法数字:状态枚举使用数字 0-4
  • 建议:保持现状,因为已经使用了有意义的枚举名称
  1. 字符串处理
QString jsonFileName = QString(jsonFileName).replace("\n", "\\n").replace("\r", "\\r");
  • 建议:封装成一个工具函数,提高可读性和复用性

性能

优点

  1. 原子操作:使用 QAtomicPointer 和 QAtomicInteger 实现无锁或低锁操作
  2. 延迟删除:使用 deleteLater() 避免立即删除可能导致的崩溃

问题与建议

  1. 频繁的 QMetaObject::invokeMethod 调用
  • 问题:每个属性更新都需要跨线程调用
  • 建议:考虑批量更新或使用更高效的线程间通信机制
  1. 字符串比较
if (key == QStringLiteral("array")) {
  • 建议:对于频繁比较的字符串,可以考虑使用枚举或整数 ID 来优化

安全性

优点

  1. 线程安全:通过原子操作和状态机确保线程安全
  2. 对象保护:使用 QPointer 避免悬空指针
  3. 防止线程迁移:通过 event 处理防止对象被错误地移动到其他线程

问题与建议

  1. 空指针检查不足
auto config = m_data->m_config.loadRelaxed();
if (!config) return;
  • 建议:在所有访问 m_config 的地方都添加空指针检查
  1. 状态转换安全性
if (!safeData->m_status.testAndSetOrdered(...)) {
    return;
}
  • 建议:添加状态转换日志,便于调试
  1. 错误处理
if (!config || !config->isValid()) {
    qWarning() << QLatin1String("Failed to create DConfig instance.");
    // ...
}
  • 建议:考虑提供更详细的错误信息,包括失败原因

其他建议

  1. 文档:建议添加类级别的文档注释,说明:

    • 类的用途
    • 线程模型
    • 使用示例
  2. 测试:建议添加单元测试,特别是:

    • 线程安全性测试
    • 对象生命周期测试
    • 并发访问测试
  3. 代码生成工具:main.cpp 中的代码生成逻辑可以考虑:

    • 添加更多配置选项
    • 支持自定义模板
    • 优化生成的代码格式

总结

这段代码在线程安全性和对象生命周期管理方面有显著改进,但在错误处理、性能优化和代码复用方面还有提升空间。建议重点关注:

  1. 增强 Release 模式下的错误检查
  2. 优化频繁的字符串比较和跨线程调用
  3. 添加更全面的错误处理和日志
  4. 提高代码复用性,减少重复代码

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants