From f18f97c84b943b239f817c17fdc0f4a730b3e206 Mon Sep 17 00:00:00 2001 From: liujianqiang Date: Wed, 24 Jun 2026 13:59:19 +0800 Subject: [PATCH] fix(dfm-io): drain GLib deferred callbacks after g_file_enumerate_children MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit g_file_enumerate_children() internally creates and destroys temporary GDBusProxy instances (mount tracker proxy, daemon proxy) whose finalization defers the weak_ref_free callback to the thread-default GMainContext via call_destroy_notify() as a g_idle_source. In a QThread without a GLib main loop, these idle sources are never dispatched, causing the GWeakRef allocations (8 bytes each from gdbusproxy.c:112) to leak. Iterate the thread-default GMainContext immediately after the GVFS enumeration call to process the deferred callbacks while still on the same thread. Log: Fixed 8-byte GWeakRef memory leak triggered by GVFS trash enumeration. Assisted-by: deepseek-v4-pro Influence: 1. Enumerate trash:/// under Valgrind — verify zero definitely-lost bytes at weak_ref_new 2. Test trash directory traversal with daemon running and file manager not in background 3. Verify normal file enumeration (local paths) is unaffected 4. Verify enumerate with timeout (QtConcurrent path) is unaffected 5. Verify rapid open/close of trash window does not accumulate leaks fix(dfm-io): 在 g_file_enumerate_children 后处理 GLib 延迟回调,修复 GWeakRef 泄露 g_file_enumerate_children() 内部会创建并销毁临时的 GDBusProxy 实例 (mount tracker proxy 和 daemon proxy),其析构时通过 call_destroy_notify() 将 weak_ref_free 回调以 g_idle_source 的形式 挂载到线程默认的 GMainContext。在没有 GLib 主循环的 QThread 中, 这些 idle source 永远不会被调度,导致 GWeakRef 分配(每次 8 字节, 来自 gdbusproxy.c:112)泄露。 在 GVFS 枚举调用返回后立即迭代线程默认的 GMainContext, 在同一个线程上处理延迟回调,避免泄露。 Log: 修复 GVFS 回收站枚举时触发的 8 字节 GWeakRef 内存泄露。 Influence: 1. Valgrind 下枚举 trash:/// — 验证 weak_ref_new 处零 definitely lost 2. 测试 daemon 运行且文件管理器未驻留时回收站目录遍历 3. 验证普通本地文件枚举不受影响 4. 验证带超时的枚举(QtConcurrent 路径)不受影响 5. 验证快速打开/关闭回收站窗口不累积泄露 --- src/dfm-io/dfm-io/denumerator.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/dfm-io/dfm-io/denumerator.cpp b/src/dfm-io/dfm-io/denumerator.cpp index 6c129566..6ddee7f7 100644 --- a/src/dfm-io/dfm-io/denumerator.cpp +++ b/src/dfm-io/dfm-io/denumerator.cpp @@ -95,6 +95,18 @@ bool DEnumeratorPrivate::createEnumerator(const QUrl &url, QPointer