Skip to content

Commit 2836fda

Browse files
craig7351claude
andcommitted
fix(monitor): stop leaking Process handles in system_stats
system_stats() backs the status-footer RSS/CPU indicators and is polled every 2 s from the frontend. It called sys.refresh_all(), which enumerates every process on the system and OpenProcess-es each one. On a terminal that constantly spawns short-lived processes, those Process handles leaked steadily, growing nonpaged pool until the machine ran out of memory and the UI froze after several hours of uptime. We only need our own process's RSS + CPU, so scope the refresh to our pid via refresh_processes(ProcessesToUpdate::Some(&[pid]), true) — matching the memory-breadcrumb loop. No handle leak, and far cheaper per poll. Bump version to 1.1.4. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 9c7c4aa commit 2836fda

4 files changed

Lines changed: 11 additions & 5 deletions

File tree

‎package-lock.json‎

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "bookshell",
3-
"version": "1.1.3",
3+
"version": "1.1.4",
44
"description": "BOOKSHELL — SSH terminal for AI agents (Phase 0 prototype)",
55
"type": "module",
66
"scripts": {

‎src-tauri/src/monitor.rs‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,13 @@ pub async fn system_stats() -> Result<SystemStats, String> {
3333
});
3434
let mut g = monitor.lock().map_err(|e| format!("lock: {}", e))?;
3535
let pid = g.pid;
36-
g.sys.refresh_all();
36+
// Refresh ONLY our own process. refresh_all() enumerates every process on the
37+
// system and, on Windows, OpenProcess-es each one. Called every 2 s from the
38+
// frontend — on a terminal that constantly spawns short-lived processes — that
39+
// leaked Process handles steadily (nonpaged-pool growth → eventual freeze).
40+
// We only need our own RSS + CPU, so scope the refresh to our pid.
41+
g.sys
42+
.refresh_processes(sysinfo::ProcessesToUpdate::Some(&[pid]), true);
3743
let proc = g.sys.process(pid).ok_or("process not found")?;
3844
Ok(SystemStats {
3945
rss_mb: proc.memory() / (1024 * 1024),

‎src-tauri/tauri.conf.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "https://schema.tauri.app/config/2",
33
"productName": "BOOKSHELL",
4-
"version": "1.1.3",
4+
"version": "1.1.4",
55
"identifier": "dev.bookshell.app",
66
"build": {
77
"beforeDevCommand": "npm run dev",

0 commit comments

Comments
 (0)