Skip to content

fix: handle removal of pending app items#715

Merged
deepin-bot[bot] merged 1 commit intolinuxdeepin:masterfrom
qxp930712:master
Mar 2, 2026
Merged

fix: handle removal of pending app items#715
deepin-bot[bot] merged 1 commit intolinuxdeepin:masterfrom
qxp930712:master

Conversation

@qxp930712
Copy link

  1. Add check for pending app items in watchingAppItemRemoved
  2. Handle cleanup of items in m_pendingAppItems container
  3. Prevent potential memory leaks from unmanaged pending items
  4. Ensure early return logic to avoid processing invalid active items
  5. Improve app lifecycle management during installation or initialization

Influence:

  1. Test removing applications while they are in a pending state
  2. Verify system stability when cancelling app installations
  3. Check logs for "Removing pending app item" debug messages
  4. Monitor for memory leaks during repeated app install/remove cycles
  5. Ensure app icons disappear correctly after pending removal

PMS: BUG-347859

1. Add check for pending app items in watchingAppItemRemoved
2. Handle cleanup of items in m_pendingAppItems container
3. Prevent potential memory leaks from unmanaged pending items
4. Ensure early return logic to avoid processing invalid active items
5. Improve app lifecycle management during installation or
initialization

Influence:
1. Test removing applications while they are in a pending state
2. Verify system stability when cancelling app installations
3. Check logs for "Removing pending app item" debug messages
4. Monitor for memory leaks during repeated app install/remove cycles
5. Ensure app icons disappear correctly after pending removal

PMS: BUG-347859
Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Sorry @qxp930712, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@deepin-ci-robot
Copy link

deepin pr auto review

这段代码主要是在处理应用项移除时的逻辑,增加了一个针对“待处理应用项”的检查分支。以下是对这段代码的详细审查和改进建议:

1. 语法与逻辑审查

  • 语法正确性:代码语法符合 C++ 标准,使用了 Qt 的容器类(QHashQMap)和日志宏,没有明显的语法错误。
  • 逻辑正确性
    • 逻辑流程清晰:先检查是否在 m_pendingAppItems 中,如果存在则移除并提前返回;否则继续处理 m_appItems 中的逻辑。
    • 潜在逻辑风险:代码中使用了 m_pendingAppItems.value(key) 获取指针,紧接着调用了 m_pendingAppItems.remove(key)。虽然逻辑上没问题,但在多线程环境下,如果 m_pendingAppItems 是共享资源,这种“读-删”操作不是原子的。不过,根据上下文推测这通常运行在主线程或特定的事件循环中,风险较低。

2. 代码质量

  • 可读性:代码结构清晰,注释说明了意图。
  • 资源管理
    • 使用了 delete pendingAppItem; 来释放内存。这要求 pendingAppItem 必须是堆分配的对象,且 m_pendingAppItems 不拥有对象的所有权(或者说是裸指针管理)。
    • 改进建议:在现代 C++ (C++11 及以后) 和 Qt 开发中,建议使用 QScopedPointerQSharedPointer 来管理动态分配的对象,以避免手动 delete 带来的内存泄漏风险(例如如果在 delete 之前发生异常或提前返回)。
  • 一致性
    • 原代码中获取 appItem 使用了 auto appItem = m_appItems.value(key);
    • 新代码中获取 pendingAppItem 也使用了 auto。风格保持一致。

3. 代码性能

  • 查找效率
    • m_pendingAppItems.contains(key)m_pendingAppItems.value(key) 分别进行了一次哈希查找。
    • 改进建议:可以合并为一次查找,使用 QHash::iteratorfind() 方法,减少哈希表的计算开销。
  • 日志开销qCDebug 在 Debug 模式下会有字符串拼接开销,但在 Release 模式下通常会被优化掉,影响不大。

4. 代码安全

  • 空指针解引用风险
    • if (m_pendingAppItems.contains(key)) 保证了 pendingAppItem 一定存在,因此 pendingAppItem->id 是安全的。
    • 但如果 m_pendingAppItems 中存储了 nullptr,虽然 contains 返回 true,但 pendingAppItem->id 会导致崩溃。不过通常容器中不应存空指针,这属于数据维护层面的约定。
  • 内存泄漏风险
    • 如果 m_pendingAppItems 中的对象没有被正确移除(例如其他路径遗漏了删除),会导致内存泄漏。
    • 如果 AppMgr 析构时没有遍历清理 m_pendingAppItems,也会导致内存泄漏。

改进后的代码建议

结合上述分析,建议优化查找次数,并使用更安全的指针管理方式(如果项目允许使用智能指针)。

void AppMgr::watchingAppItemRemoved(const QString &key)
{
    // Check if the item is in pending container
    // 使用 take() 方法,原子性地取出对象并移除键,避免两次查找
    auto pendingAppItem = m_pendingAppItems.take(key);
    
    if (pendingAppItem) {
        qCDebug(logDdeIntegration) << "Removing pending app item, desktopId:" << pendingAppItem->id;
        
        // 如果项目支持 C++11/14,建议使用 deleteLater() 确保安全删除(如果是 QObject 派生类)
        // 或者使用智能指针管理,这里假设 pendingAppItem 是 QObject 派生类
        pendingAppItem->deleteLater(); 
        return;
    }
    
    // 原有逻辑
    auto appItem = m_appItems.value(key);
    if (!appItem) {
        qCWarning(logDdeIntegration) << "App item not found for key:" << key;
        // ...
    }
    // ...
}

改进点总结:

  1. 性能优化:使用 take(key) 替代 contains + value + removetake 会执行一次查找,移除键并返回对应的值。这不仅减少了查找次数,还保证了操作的原子性(在单线程语境下)。
  2. 安全性增强
    • 如果 AppItem 继承自 QObject,强烈建议使用 deleteLater() 而不是直接 delete。这可以防止在对象的事件循环中还有未处理事件时直接销毁对象导致的崩溃。
    • 如果 AppItem 不是 QObject,请确保在析构函数中清理 m_pendingAppItems 剩余项,或者考虑使用 QSharedPointer 自动管理生命周期。
  3. 防御性编程take 在 key 不存在时返回默认构造值(对于指针来说是 nullptr),所以 if (pendingAppItem) 检查依然有效且安全。

如果 AppItem 不是 QObject 的子类,且必须手动管理内存,代码应如下:

    auto pendingAppItem = m_pendingAppItems.take(key);
    if (pendingAppItem) {
        qCDebug(logDdeIntegration) << "Removing pending app item, desktopId:" << pendingAppItem->id;
        delete pendingAppItem;
        return;
    }

@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: BLumia, qxp930712

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

@BLumia
Copy link
Member

BLumia commented Mar 2, 2026

/merge

@deepin-bot deepin-bot bot merged commit 0a44aee into linuxdeepin:master Mar 2, 2026
10 checks passed
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