fix(renderer): prevent display teardown starvation during output floods
Closing a busy split or confirming a tab close could freeze GTK while unrealizing the GLArea. Both reported GDB traces show the main thread waiting for the CPU frame-state mutex while the renderer keeps rebuilding dense text. GTK unrealizes the display before stopping the workers, so continuous output can keep the competing renderer active indefinitely. Use parking_lot fair mutexes for CPU frame state and GPU draw state. A waiting lifecycle or draw callback receives ownership instead of losing it to the next frame update. Keep the existing lock order and resource cleanup; no output, scrollback, or frame-rate limits are introduced. The fair-lock handoff adds scheduling overhead when the locks are contended. Correct the threading documentation: the CPU state is also accessed by apprt callbacks, and the Rust-only mutex is therefore contended. Test plan: - Add a mock GPU regression continuously rebuilding 200x150 dense cells while another thread unrealizes and realizes the display. It failed its three-second deadline with the old locks and passes with fair locks. - All 235 renderer/core tests pass, including Mesa EGL rendering tests. - Clippy for renderer/core/GTK, all targets, passes with -D warnings. - Nightly formatting check and release binary build pass. - GTK/Wayland replay with font size 9 and 1 GiB scrollback runs base64 floods in two splits, confirms split and tab closes, then successfully executes and renders a command in the surviving terminal. Docs: docs/rewrite/ARCHITECTURE.md
This commit is contained in:
1 parent
9010117d08
commit
2e5ec06b4e
5 files changed
+124
-40
No files matched your search
@@ -32,6 +32,8 @@ ghostty (bin, src/main.rs) CLI `+action` dispatch or GTK app startup
|
||||
│ ├── kitty / search / tmux kitty graphics, search thread, tmux control mode
|
||||
│ └── ghostty-vt byte stream -> Parser -> Stream -> Handler actions
|
||||
├── ghostty-renderer OpenGL renderer (glow), renderer thread, shaders
|
||||
│ ├── generic::Renderer CPU frame state + GPU draw state; fair mutexes
|
||||
│ │ let GTK display teardown run during output
|
||||
│ └── ghostty-font fontconfig/freetype/harfbuzz, sprite font, atlas
|
||||
├── ghostty-inspector Dear ImGui terminal inspector
|
||||
└── ghostty-config config file/CLI parsing, themes, keybinds
|
||||
@@ -128,6 +130,12 @@ GTK invokes `glib-compile-resources` directly so generated XML/UI files in
|
||||
thread, plus a pty read thread. Mailboxes are `crossbeam-channel` /
|
||||
`std::sync::mpsc`; the GTK main thread is woken via `glib` channels.
|
||||
The `Terminal` is shared behind `Arc<Mutex<..>>` (Ghostty's renderer mutex).
|
||||
The generic renderer uses fair mutexes for its CPU frame and GPU draw state:
|
||||
continuous frame updates hand ownership to waiting GTK lifecycle/draw
|
||||
callbacks. Closing a tab/split unrealizes its GLArea before worker shutdown;
|
||||
teardown must acquire these locks while the PTY is still producing output.
|
||||
This is a Rust synchronization fix; Zig does not have the extra CPU-state
|
||||
mutex used by the rewrite.
|
||||
`ghostty-core::App` handles at most 64 mailbox messages per tick and wakes
|
||||
the runtime again if work remains. Continuous renderer notifications must
|
||||
yield to GTK input, timers, and drawing instead of extending one tick
|
||||
|
||||
Reference in new issue
Block a user