diff options
| author | Can Celik <ogulcancelik@gmail.com> | 2026-09-15 21:17:32 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-09-15 21:17:32 +0300 |
| commit | 4428e1664d8d897ce2f914777c0fe060cf334c84 (patch) | |
| tree | b0074802c17cd609f77c1a230a2fd7f2b396d943 /src/app | |
| parent | f70a1f835ef614f5e1ad1bde76d4629c650fd192 (diff) | |
fix: preserve unloaded sessions before replacement (#4190)
refs #4125
Diffstat (limited to 'src/app')
| -rw-r--r-- | src/app/mod.rs | 10 | ||||
| -rw-r--r-- | src/app/session.rs | 25 |
2 files changed, 24 insertions, 11 deletions
diff --git a/src/app/mod.rs b/src/app/mod.rs index 4ac109c7..757a7f66 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -138,6 +138,7 @@ pub struct App { pub(crate) pending_agent_resume_deadline: Option<Instant>, pub(crate) session_save_deadline: Option<Instant>, pub(crate) session_save_thread: Option<std::thread::JoinHandle<()>>, + session_writer: Arc<std::sync::Mutex<crate::persist::SessionWriter>>, pane_exit_checkpoint_pending: bool, pub(crate) detached_process_children: Vec<std::process::Child>, tab_bar_status_generation: u64, @@ -370,9 +371,11 @@ impl App { // Try to restore previous session let mut restored_terminals = std::collections::HashMap::new(); let mut restored_terminal_runtimes = crate::terminal::TerminalRuntimeRegistry::new(); - let (workspaces, active, selected) = if !policy.restore_session { - (Vec::new(), None, 0) - } else if let Some(snap) = crate::persist::load() { + let snapshot = policy.restore_session.then(crate::persist::load).flatten(); + let session_writer = Arc::new(std::sync::Mutex::new(crate::persist::SessionWriter::new( + policy.restore_session && snapshot.is_none(), + ))); + let (workspaces, active, selected) = if let Some(snap) = snapshot { let history = config .experimental .pane_history @@ -599,6 +602,7 @@ impl App { pending_agent_resume_deadline: None, session_save_deadline: None, session_save_thread: None, + session_writer, pane_exit_checkpoint_pending: false, detached_process_children: Vec::new(), tab_bar_status_generation: 0, diff --git a/src/app/session.rs b/src/app/session.rs index 49dca914..08c4cd44 100644 --- a/src/app/session.rs +++ b/src/app/session.rs @@ -70,14 +70,15 @@ impl App { let job = self.capture_session_save_job(); self.pane_exit_checkpoint_pending = false; self.session_save_deadline = None; + let writer = self.session_writer.clone(); match std::thread::Builder::new() .name("herdr-session-save".into()) - .spawn(move || run_session_save_job(job)) + .spawn(move || run_session_save_job(job, &writer)) { Ok(thread) => self.session_save_thread = Some(thread), Err(err) => { tracing::warn!(err = %err, "failed to spawn session save thread; saving inline"); - run_session_save_job(self.capture_session_save_job()); + run_session_save_job(self.capture_session_save_job(), &self.session_writer); } } } @@ -92,7 +93,7 @@ impl App { return; } - run_session_save_job(self.capture_session_save_job()); + run_session_save_job(self.capture_session_save_job(), &self.session_writer); self.pane_exit_checkpoint_pending = false; self.session_save_deadline = None; } @@ -124,11 +125,19 @@ impl App { } } -fn run_session_save_job(job: SessionSaveJob) { - match job { - SessionSaveJob::Clear => crate::persist::clear(), - SessionSaveJob::Save { snapshot, history } => { - crate::persist::save(&snapshot, history.as_ref()); +fn run_session_save_job( + job: SessionSaveJob, + writer: &std::sync::Mutex<crate::persist::SessionWriter>, +) { + let mut writer = match writer.lock() { + Ok(writer) => writer, + Err(err) => { + tracing::warn!(err = %err, "session writer is poisoned; refusing to modify session"); + return; } + }; + match job { + SessionSaveJob::Clear => writer.clear(), + SessionSaveJob::Save { snapshot, history } => writer.save(&snapshot, history.as_ref()), } } |
