GTK: audio bell leaks a GStreamer pipeline + GL-context threads per ring (idle CPU climbs over time) #12808
Issue DescriptionWith After ~1.5 days of normal use (multiple long-lived TUI sessions that ring the bell on completion), a single Ghostty process had accumulated 3,482 threads and was consuming ~3 CPU cores while idle. Thread-name histogram from That is ~696 GStreamer playbin/GL pipelines that were never freed — almost exactly one per bell rung. The leaked threads are parked in Root cause (from source)
Cleanup relies solely on if (required) {
_ = gobject.Object.signals.notify.connect(media_file, ..., .{ .detail = "error" });
}
// "ended" handler always connected; calls media_file.unref()So for an optional The 100 ms per-surface BEL rate-limit (#9810, present since 1.3.0) caps the acute DoS freeze but does nothing for this slow per-bell leak, since legitimate bells fire far below 10/s. This is the same Expected BehaviorRinging the audio bell N times leaves the thread/pipeline count bounded (ideally constant), and idle CPU returns to baseline after playback finishes. Actual BehaviorEach audio bell leaks a GStreamer pipeline and its GL threads. Thread count and idle CPU grow without bound over the lifetime of the process. Reproduction Steps
Ghostty LogsNo response Ghostty Version(Code path is unchanged on OS Version InformationArch Linux. GTK 4.22.4, libadwaita 1.9.0, GStreamer 1.28.3 (gst-plugins-base/good 1.28.3). Default (GStreamer) GTK media backend ( (Linux only) Display ServerWayland (Linux only) Desktop Environment/Window ManagerNo response Minimal Ghostty Configurationbell-features = audio,attention,title,border
bell-audio-path = /path/to/bell.ogaAdditional Relevant ConfigurationTriggered in practice by long-lived TUI programs that ring the bell on each completion (e.g. AI coding agents), accumulating hundreds of bells over a multi-day session. Suggested fixes
Open question for maintainersDoes the leak occur on the happy path (i.e. does the GStreamer GTK4/GL backend fail to join |
#13647