a8d0cf0f by 柴进

:bug: 修复 task_queue 信号 lambda connect 跨线程 GUI 调用导致的 access violation

faulthandler 抓到 7 个 Windows access violation 栈, 全部归到同一根因:
worker_ref.finished/error/progress (QThread 信号) 和 task_completed 用
lambda connect 时, lambda 没有 QObject thread affinity, Qt 默认按
DirectConnection 处理, 导致 lambda 在 worker 线程同步执行, 链路尽头
动主线程 GUI (refresh_history / _update_summary / display_image) →
C++ 层 access violation。

Windows 表现为 fatal exception: access violation, 用户感知"crash";
macOS 触发后多被 SIGKILL 静默闪退, faulthandler 拦不到, 这就是最近
"Mac 仍闪退"剩余尾巴的同源问题。

修复: 5 处 lambda connect 全部显式 Qt.QueuedConnection, 强制 handler
进 receiver 主线程 event loop 排队, 彻底消除跨线程 GUI 调用。
1 parent 5f2a43f7
......@@ -3092,9 +3092,12 @@ class ImageGeneratorWindow(QMainWindow):
)
# Connect to task completion signal
# 🔒 QueuedConnection: lambda 没有 QObject receiver, 不强制排队的话会被当 DirectConnection,
# 在发射方所在线程同步执行 → 跨线程动 GUI → access violation (Win) / 静默闪退 (Mac)
self.task_manager.task_completed.connect(
lambda tid, img, p, refs, ar, size, model:
self._on_my_task_completed(task_id, tid, img, p, refs, ar, size, model)
self._on_my_task_completed(task_id, tid, img, p, refs, ar, size, model),
Qt.QueuedConnection,
)
# Update UI
......@@ -4681,9 +4684,11 @@ class StyleDesignerTab(QWidget):
)
# Connect to task completion signal
# 🔒 QueuedConnection 同上, 防 lambda 在 worker 线程被 DirectConnection 同步触发
self.parent_window.task_manager.task_completed.connect(
lambda tid, img, p, refs, ar, size, mdl:
self._on_my_task_completed(task_id, tid, img, p, refs, ar, size, mdl)
self._on_my_task_completed(task_id, tid, img, p, refs, ar, size, mdl),
Qt.QueuedConnection,
)
# Update UI
......
......@@ -206,17 +206,24 @@ class TaskQueueManager(QObject):
# 绑定信号;用 worker 局部引用捕获 finish_reason,避免后续 _current_worker 被替换
worker_ref = self._current_worker
# 🔒 必须 QueuedConnection: worker_ref 是 QThread, finished/error/progress 从 worker 线程发出。
# lambda 没有 QObject thread affinity, 默认会被当成 DirectConnection 在 worker 线程同步执行,
# 链路尽头会动主线程 GUI (refresh_history / _update_summary), C++ 层 access violation。
# Windows 表现为 fatal exception, macOS 表现为静默 SIGKILL 闪退。
worker_ref.finished.connect(
lambda img_bytes, prompt, ref_imgs, ar, size, model:
self._on_task_completed(task_id, img_bytes, prompt, ref_imgs, ar, size, model,
getattr(worker_ref, 'finish_reason', None))
getattr(worker_ref, 'finish_reason', None)),
Qt.QueuedConnection,
)
worker_ref.error.connect(
lambda error: self._on_task_failed(task_id, error,
getattr(worker_ref, 'finish_reason', None))
getattr(worker_ref, 'finish_reason', None)),
Qt.QueuedConnection,
)
worker_ref.progress.connect(
lambda status: self.task_progress.emit(task_id, 0.5, status)
lambda status: self.task_progress.emit(task_id, 0.5, status),
Qt.QueuedConnection,
)
self.task_started.emit(task_id)
......