Skip to content

Conversation

@wangrong1069
Copy link
Contributor

@wangrong1069 wangrong1069 commented Jan 6, 2026

Summary by Sourcery

Replace the custom timer stop flag in the event handler with a GCancellable-based cancellation mechanism for the background timer worker.

Enhancements:

  • Introduce a GCancellable member in base_event_handler and use it to control and wait for timer worker cancellation instead of an atomic boolean flag.
  • Add a helper function that integrates GCancellable with g_poll to support interruptible timed waits in the timer worker loop.
  • Tidy includes in main.cpp and base_event_handler headers, adding gio dependency for GCancellable usage.

- Replace std::atomic<bool> stop_timer_ with GCancellable* cancellable_
- Add cancellable_wait helper function for polling cancellation with timeout
- Refactor timer_worker loop to use cancellable_wait instead of sleep loop
- Include necessary <gio/gio.h> header
- Adjust Qt header order in main.cpp for compilation error

This change improves cancellation responsiveness and reduces CPU usage
by leveraging GLib's cancellation mechanism.

Bug: https://pms.uniontech.com/bug-view-339241.html
@github-actions
Copy link

github-actions bot commented Jan 6, 2026

TAG Bot

TAG: 7.0.36
EXISTED: no
DISTRIBUTION: unstable

@sourcery-ai
Copy link

sourcery-ai bot commented Jan 6, 2026

Reviewer's Guide

Refactors the base_event_handler timer thread to use a GLib GCancellable and pollable FD for cooperative cancellation instead of a custom atomic flag and std::this_thread::sleep_for, and wires in the necessary GLib/GIO headers and object lifetime management.

Class diagram for updated base_event_handler timer cancellation

classDiagram
    class base_event_handler {
        +base_event_handler(event_handler_config config)
        +~base_event_handler()
        +void terminate_processing()
        +void timer_worker(int64_t interval)
        -- timer_and_jobs_state --
        -anything::index_manager index_manager_
        -std::size_t batch_size_
        -anything::thread_pool pool_
        -GCancellable* cancellable_
        -bool delay_mode_
        -bool index_dirty_
        -bool volatile_index_dirty_
        -std::vector<std::string> pending_paths_
        -std::vector<anything::index_job> jobs_
        -std::mutex jobs_mtx_
        -std::mutex pending_mtx_
        -std::thread timer_
        -std::atomic<bool> stop_scan_directory_
    }

    class GCancellable {
        +GCancellable* g_cancellable_new()
        +void g_cancellable_cancel(GCancellable* cancellable)
        +gboolean g_cancellable_is_cancelled(GCancellable* cancellable)
        +int g_cancellable_get_fd(GCancellable* cancellable)
        +void g_cancellable_release_fd(GCancellable* cancellable)
    }

    class GLibFunctions {
        +gint g_poll(GPollFD* fds, guint nfds, gint timeout_ms)
        +void g_usleep(gulong microseconds)
    }

    base_event_handler --> GCancellable : uses
    base_event_handler --> GLibFunctions : uses
Loading

File-Level Changes

Change Details Files
Replace custom atomic stop flag and blocking sleep with GCancellable-based cancellation and FD polling in the timer worker thread.
  • Initialize a GCancellable in base_event_handler constructor and store it as a member pointer instead of an atomic stop flag.
  • Unref the GCancellable in the base_event_handler destructor to manage GLib object lifetime.
  • Change terminate_processing() to cancel the GCancellable instead of toggling the stop flag, while preserving directory scan termination and timer thread join logic.
  • Introduce a static helper cancellable_wait() that either sleeps for the timeout or polls the GCancellable’s FD using g_poll(), returning early when cancellation is signalled.
  • Update timer_worker() to obtain the cancellable FD, loop until cancellable_wait() indicates cancellation, and release the FD via g_cancellable_release_fd() at the end, removing the explicit std::this_thread::sleep_for interval wait.
src/daemon/src/core/base_event_handler.cpp
src/daemon/include/core/base_event_handler.h
Adjust includes to support GCancellable and tidy Qt include ordering.
  • Add <gio/gio.h> include to base_event_handler header so GCancellable is available.
  • Reorder Qt includes in main.cpp after project headers to maintain consistent style while keeping QCoreApplication and QTimer usage intact.
src/daemon/include/core/base_event_handler.h
src/daemon/src/main.cpp

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

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.

Hey - I've found 1 issue, and left some high level feedback:

  • In timer_worker, g_cancellable_release_fd(cancellable_) is called unconditionally even if g_cancellable_get_fd() returned -1; per the GLib API you should only call g_cancellable_release_fd() when a valid fd was obtained, so guard the release call with if (cancellable_fd != -1).
  • Consider moving the g_cancellable_get_fd(cancellable_) call inside timer_worker closer to where it's needed and handling the -1 case explicitly (e.g., by falling back to g_usleep or skipping g_poll), to make the control flow and behaviour clearer when an fd-backed cancellable isn't available.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `timer_worker`, `g_cancellable_release_fd(cancellable_)` is called unconditionally even if `g_cancellable_get_fd()` returned `-1`; per the GLib API you should only call `g_cancellable_release_fd()` when a valid fd was obtained, so guard the release call with `if (cancellable_fd != -1)`.
- Consider moving the `g_cancellable_get_fd(cancellable_)` call inside `timer_worker` closer to where it's needed and handling the `-1` case explicitly (e.g., by falling back to `g_usleep` or skipping `g_poll`), to make the control flow and behaviour clearer when an fd-backed cancellable isn't available.

## Individual Comments

### Comment 1
<location> `src/daemon/src/core/base_event_handler.cpp:324-329` </location>
<code_context>
-        //     }
-        // }
-        // std::this_thread::sleep_for(std::chrono::milliseconds(interval));
+    int cancellable_fd = g_cancellable_get_fd(cancellable_);

+    while(!cancellable_wait(cancellable_, cancellable_fd, (gint)interval)) {
</code_context>

<issue_to_address>
**issue (bug_risk):** Guard g_cancellable_release_fd() with a check for a valid fd from g_cancellable_get_fd().

Per the GLib docs, g_cancellable_release_fd() must only be called if g_cancellable_get_fd() returned a non-negative value. In timer_worker(), release_fd() is invoked unconditionally, which can cause undefined behavior when cancellable_fd == -1. Please guard the release call with a check (e.g., only call it when cancellable_fd != -1).
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

As title.

Log: Update version to 7.0.36
@deepin-ci-robot
Copy link

deepin pr auto review

我来对这个diff进行详细的代码审查:

  1. 代码逻辑改进:
  • 将std::atomic stop_timer_替换为GCancellable *cancellable_是一个很好的改进。GCancellable是GLib提供的标准取消机制,更适合处理异步操作的取消,比简单的原子布尔值更灵活和强大。
  1. 代码质量:
  • 新增的cancellable_wait函数实现合理,处理了各种边界情况:
    • 检查cancellable是否已被取消
    • 处理无效文件描述符的情况
    • 正确处理超时和错误情况
    • 在错误情况下有适当的日志记录
  • 资源管理正确:在构造函数中创建cancellable_,在析构函数中释放
  1. 代码性能:
  • 使用g_poll替代std::this_thread::sleep_for是更好的选择,因为:
    • g_poll可以立即响应取消信号
    • 避免了sleep期间无法响应取消的问题
    • 减少了CPU资源浪费
  1. 代码安全:
  • 正确处理了文件描述符的获取和释放
  • 添加了适当的错误处理和日志记录
  • 使用了GLib的标准取消机制,更安全可靠
  1. 其他建议:
  • 在cancellable_wait函数中,当g_poll返回错误时,除了记录警告日志,可以考虑是否需要更严格的错误处理
  • 可以考虑为cancellable_wait函数添加更详细的文档注释,说明参数和返回值的具体含义
  • 建议在构造函数中检查cancellable_是否创建成功
  1. 版本更新:
  • changelog的更新符合规范,清晰说明了本次更新的主要内容

总体来说,这是一个质量较高的代码改进,提高了代码的可靠性和响应性。使用GLib的标准机制替代自定义的原子变量是一个明智的选择。

@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: lzwind, wangrong1069

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

@lzwind lzwind merged commit e2ffc2d into linuxdeepin:develop/snipe Jan 6, 2026
19 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.

3 participants