fix(desktop): fix app freeze when installing auto-update on macOS#3138
Merged
Conversation
Clicking the auto-update install button freezes the app on macOS (and would also affect Windows) instead of exiting to let the update script take over. Root cause: install() runs on the AWT EDT, where it called exitProcess(0). System.exit blocks the calling thread until all JVM shutdown hooks finish, but since #3067 the JCEF cleanup hook uses SwingUtilities.invokeAndWait to dispose CefApp on the EDT. The EDT waits for the hook while the hook waits for the EDT, deadlocking forever, so the old process never exits and the external update script waits indefinitely. Fix: - Exit the process from a background thread instead of the EDT, so the EDT stays free to process the CEF disposal during shutdown. Also removes the 1s UI freeze from Thread.sleep on the EDT. - Make the JCEF shutdown hook wait for EDT disposal with a 5s bound instead of indefinitely, so any future System.exit from the EDT can no longer freeze the process. Verified with a minimal AWT reproduction: the old code deadlocks permanently when exiting on the EDT with a blocking hook; the fixed flow disposes CEF cleanly and exits, and the worst case (exit on EDT) now exits after the 5s timeout. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
问题
macOS 上点击自动更新的"安装"按钮后,app 不再自动关闭,而是直接冻结,更新无法完成。Windows 理论上也受影响。
根因
install()由 Compose 点击回调调用,运行在 AWT EDT 上,并直接调用了exitProcess(0):System.exit会阻塞调用线程(EDT),等待所有 JVM shutdown hook 完成;runOnCefContext(invokeLater)改成了disposeAppBlocking→blockOnCefContext→SwingUtilities.invokeAndWait,即阻塞等待 EDT 来执行 CefApp dispose;while kill -0 $OLD_PID一直等旧进程退出,更新永远不会安装。正常关窗/托盘退出不受影响,因为那条路径先在 EDT 内联执行了
AniCefApp.disposeBlocking(),hook 里disposedApps去重后变 no-op;只有更新安装路径绕过了它直接exitProcess。JCEF 在启动时必然初始化,hook 必然注册,所以所有 macOS 用户点更新 100% 冻结。修复(双保险)
exitProcess(0)挪到后台线程exitProcessForUpdate,install()返回Succeed。EDT 保持空闲,shutdown 期间 CEF 能正常在 EDT 上 dispose。顺带消除了原来Thread.sleep(1000)卡 UI 一秒的问题。invokeAndWait无限等待,改为invokeLater+CountDownLatch5 秒有界等待,超时打 warning 后继续退出。以后即使再有代码从 EDT 直接System.exit,最坏 5 秒后退出,不可能再永久冻结。EDT 上调用行为不变(内联执行),正常退出路径不受影响。验证
:app:shared:app-platform:compileKotlinDesktop+:app:shared:compileKotlinDesktopBUILD SUCCESSFUL。invokeAndWaithook + EDT 上 exit)→ 永久冻结,复现线上问题;🤖 Generated with Claude Code