From e3410e0f7c38a4daaddd6cc1de116e046f7968d5 Mon Sep 17 00:00:00 2001 From: julian Date: Sun, 15 Mar 2026 08:46:00 +0800 Subject: [PATCH] fix(linux): remove hourly server restart that destabilizes Cinnamon The --service process killed and restarted the --server subprocess every 3600 seconds (or 60 seconds after connection manager closed) as a workaround for stale DNS resolution and X display detection failures. Both issues are already handled inline without a process restart: - DNS: rendezvous_mediator.rs rebinds the UDP socket after consecutive registration failures (rebind_udp_for, DNS_INTERVAL = 60s) - Displays: display_service.rs polls for display changes every 300ms via check_get_displays_changed_msg() The hourly restart caused: - IPC disconnection errors every hour ("ipc connection closed: reset by the peer") logged in ui_interface.rs - Tray icon removed and re-registered each cycle (XAppStatusIcon churn) - _NET_ACTIVE_WINDOW messages with timestamp 0 on each server startup - Memory accumulation over multi-day uptime (peaked at 905MB) - Cinnamon/Muffin instability leading to general protection faults and fallback to Metacity after days of continuous operation Also removes the now-unused get_cm() function, cm0/last_restart parameters, and Instant import. Co-Authored-By: Claude Opus 4.6 Signed-off-by: julian --- src/platform/linux.rs | 55 +++++++------------------------------------ 1 file changed, 9 insertions(+), 46 deletions(-) diff --git a/src/platform/linux.rs b/src/platform/linux.rs index 7157da760..a3dae206e 100644 --- a/src/platform/linux.rs +++ b/src/platform/linux.rs @@ -21,7 +21,7 @@ use std::{ string::String, sync::atomic::{AtomicBool, Ordering}, sync::Arc, - time::{Duration, Instant}, + time::Duration, }; use terminfo::{capability as cap, Database}; use wallpaper; @@ -691,11 +691,8 @@ fn should_start_server( is_display_changed: bool, uid: &mut String, desktop: &Desktop, - cm0: &mut bool, - last_restart: &mut Instant, server: &mut Option, ) -> bool { - let cm = get_cm(); let mut start_new = false; let mut should_kill = false; @@ -713,29 +710,19 @@ fn should_start_server( should_kill = true; } - if !should_kill - && !cm - && ((*cm0 && last_restart.elapsed().as_secs() > 60) - || last_restart.elapsed().as_secs() > 3600) - { - let terminal_session_count = crate::ipc::get_terminal_session_count().unwrap_or(0); - if terminal_session_count > 0 { - // There are terminal sessions, so we don't restart the server. - // We also need to keep `cm0` unchanged, so that we can reach this branch the next time. - return false; - } - // restart server if new connections all closed, or every one hour, - // as a workaround to resolve "SpotUdp" (dns resolve) - // and x server get displays failure issue - should_kill = true; - log::info!("restart server"); - } + // Note: a previous hourly restart workaround was removed here. + // It killed the --server subprocess every 3600s (or 60s after CM closed) + // to work around stale DNS and display detection issues. Both are already + // handled inline without a restart: + // - DNS: rendezvous_mediator.rs rebinds UDP socket after consecutive failures + // - Displays: display_service.rs polls for changes every 300ms + // The restart caused: IPC disconnection errors, tray icon churn, memory + // accumulation, and Cinnamon/Muffin instability over multi-day uptime. if should_kill { if let Some(ps) = server.as_mut() { allow_err!(ps.kill()); sleep_millis(30); - *last_restart = Instant::now(); } } @@ -750,7 +737,6 @@ fn should_start_server( } else { start_new = true; } - *cm0 = cm; start_new } @@ -785,8 +771,6 @@ pub fn start_os_service() { println!("Failed to set Ctrl-C handler: {}", err); } - let mut cm0 = false; - let mut last_restart = Instant::now(); while running.load(Ordering::SeqCst) { desktop.refresh(); @@ -802,8 +786,6 @@ pub fn start_os_service() { false, &mut uid, &desktop, - &mut cm0, - &mut last_restart, &mut server, ) { stop_subprocess(); @@ -824,8 +806,6 @@ pub fn start_os_service() { is_display_changed, &mut uid, &desktop, - &mut cm0, - &mut last_restart, &mut user_server, ) { stop_subprocess(); @@ -871,23 +851,6 @@ pub fn get_active_userid() -> String { get_values_of_seat0(&[1])[0].clone() } -fn get_cm() -> bool { - // We use `CMD_PS` instead of `ps` to suppress some audit messages on some systems. - if let Ok(output) = Command::new(CMD_PS.as_str()).args(vec!["aux"]).output() { - for line in String::from_utf8_lossy(&output.stdout).lines() { - if line.contains(&format!( - "{} --cm", - std::env::current_exe() - .unwrap_or("".into()) - .to_string_lossy() - )) { - return true; - } - } - } - false -} - pub fn is_login_wayland() -> bool { let files = ["/etc/gdm3/custom.conf", "/etc/gdm/custom.conf"]; match (