diff --git a/reader/browser/PageRenderThread.cpp b/reader/browser/PageRenderThread.cpp index ece233bf2..89722477b 100644 --- a/reader/browser/PageRenderThread.cpp +++ b/reader/browser/PageRenderThread.cpp @@ -314,7 +314,9 @@ void PageRenderThread::appendTask(DocCloseTask task) void PageRenderThread::run() { - m_quit = false; + // 注意: 不能在这里重置 m_quit。若 destroyForever() 在线程进入 run() 前 + // 已置 m_quit=true, 此处重置会吞掉退出请求,导致 wait() 永久阻塞。 + // 实例创建时 m_quit 默认即为 false, 无需重复初始化。 qCDebug(appLog) << "====开始执行任务===="; while (!m_quit) { diff --git a/reader/browser/PageRenderThread.h b/reader/browser/PageRenderThread.h index bd732fbed..5765310ba 100644 --- a/reader/browser/PageRenderThread.h +++ b/reader/browser/PageRenderThread.h @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -283,7 +284,8 @@ private slots: QMutex m_closeMutex; QList m_closeTasks; - bool m_quit = false; + // 原子量: 主线程 destroyForever 写、渲染线程读, 避免数据竞争 + std::atomic m_quit {false}; static bool s_quitForever; diff --git a/tests/uiframe/ut_docsheet.cpp b/tests/uiframe/ut_docsheet.cpp index 82705eb19..e586cf728 100644 --- a/tests/uiframe/ut_docsheet.cpp +++ b/tests/uiframe/ut_docsheet.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2019 ~ 2020 Uniontech Software Technology Co.,Ltd. -// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2023 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -1283,6 +1283,14 @@ TEST_F(TestDocSheet, UT_DocSheet_docBasicInfo_001) TEST_F(TestDocSheet, UT_DocSheet_onBrowserPageChanged_001) { + // onBrowserPageChanged 在浏览器不可见时会忽略页码回写(防进度污染守卫), + // 单测环境不 show 窗口, isVisible 恒为 false, 需打桩绕过; + // 同时桩掉 sidebar 的 setCurrentPage, 避免触发缩略图渲染任务导致 + // PageRenderThread 在进程退出阶段 start/wait 竞争挂死 + Stub s; + s.set(ADDR(QWidget, isVisible), isVisible_stub_true); + s.set(ADDR(SheetSidebar, setCurrentPage), setCurrentPage_stub); + m_tester->m_operation.currentPage = 2; m_tester->onBrowserPageChanged(1); EXPECT_TRUE(m_tester->m_operation.currentPage == 1);