diff options
| author | Aram Drevekenin <aram@poor.dev> | 2026-03-16 22:06:41 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-03-16 22:06:41 +0100 |
| commit | a0deec573bb80fc8320d792ae62abc6e2831daa0 (patch) | |
| tree | dfc03517045a847f3d754a65031d4320983e9a88 | |
| parent | feat(themes): add Flexoki Dark theme (#4555) (diff) | |
| download | sl0ppij-a0deec573bb80fc8320d792ae62abc6e2831daa0.tar.gz sl0ppij-a0deec573bb80fc8320d792ae62abc6e2831daa0.tar.xz sl0ppij-a0deec573bb80fc8320d792ae62abc6e2831daa0.zip | |
fix: do not reuse terminal pane ids, clean up tokio tasks (#4859)
* don't reuse terminal pane_ids, perform some cleanups
* rustfmt
* add pr
| -rw-r--r-- | CHANGELOG.md | 1 | ||||
| -rw-r--r-- | zellij-server/src/os_input_output_unix.rs | 20 | ||||
| -rw-r--r-- | zellij-server/src/pty.rs | 4 | ||||
| -rw-r--r-- | zellij-server/src/screen.rs | 10 |
4 files changed, 24 insertions, 11 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 779a92e9..c59edb1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -83,6 +83,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) * feat: add --pane-id and --tab-id to all relevant CLI actions (https://github.com/zellij-org/zellij/pull/4846) * feat: add --ansi flag to all relevant CLI/plugin-api screendump commands (https://github.com/zellij-org/zellij/pull/4848) * fix: sixel aspect-ratio and padding issues (https://github.com/zellij-org/zellij/pull/4858) +* fix: don't recycle pane ids for terminals (https://github.com/zellij-org/zellij/pull/4859) ## [0.43.1] - 2025-08-08 * fix: pane rename backspace regression (https://github.com/zellij-org/zellij/pull/4346) diff --git a/zellij-server/src/os_input_output_unix.rs b/zellij-server/src/os_input_output_unix.rs index 052636b8..8c8ae6e0 100644 --- a/zellij-server/src/os_input_output_unix.rs +++ b/zellij-server/src/os_input_output_unix.rs @@ -26,7 +26,10 @@ use std::{ process::CommandExt, }, process::{Child, Command}, - sync::{Arc, Mutex}, + sync::{ + atomic::{AtomicU32, Ordering}, + Arc, Mutex, + }, thread, time::Duration, }; @@ -276,6 +279,7 @@ fn handle_terminal( pub(crate) struct UnixPtyBackend { orig_termios: Arc<Mutex<Option<termios::Termios>>>, terminal_id_to_raw_fd: Arc<Mutex<BTreeMap<u32, Option<RawFd>>>>, + next_terminal_id_counter: Arc<AtomicU32>, } /// Try to write as many bytes from `buf` as possible to `fd` without blocking. @@ -307,6 +311,7 @@ impl UnixPtyBackend { Ok(Self { orig_termios: Arc::new(Mutex::new(current_termios)), terminal_id_to_raw_fd: Arc::new(Mutex::new(BTreeMap::new())), + next_terminal_id_counter: Arc::new(AtomicU32::new(0)), }) } @@ -439,15 +444,10 @@ impl UnixPtyBackend { } pub fn next_terminal_id(&self) -> Option<u32> { - self.terminal_id_to_raw_fd - .lock() - .unwrap() - .keys() - .copied() - .collect::<BTreeSet<u32>>() - .last() - .map(|l| l + 1) - .or(Some(0)) + Some( + self.next_terminal_id_counter + .fetch_add(1, Ordering::Relaxed), + ) } } diff --git a/zellij-server/src/pty.rs b/zellij-server/src/pty.rs index c277dd64..bb9c800c 100644 --- a/zellij-server/src/pty.rs +++ b/zellij-server/src/pty.rs @@ -1761,7 +1761,9 @@ impl Pty { let err_context = || format!("failed to close for pane {id:?}"); match id { PaneId::Terminal(id) => { - self.task_handles.remove(&id); + if let Some(handle) = self.task_handles.remove(&id) { + handle.abort(); + } if let Some(child_pid) = self.id_to_child_pid.remove(&id) { let err_context = || format!("failed to kill child processes for pane {id}"); self.bus diff --git a/zellij-server/src/screen.rs b/zellij-server/src/screen.rs index aa6c64da..39fde948 100644 --- a/zellij-server/src/screen.rs +++ b/zellij-server/src/screen.rs @@ -5924,6 +5924,16 @@ pub(crate) fn screen_thread_main( }, } + // Clean up PTY-side resources (async reader task, child PID mapping, + // terminal_id_to_raw_fd entry). This is needed because the natural + // child exit path (quit_cb) only sends ScreenInstruction::ClosePane + // and never sends PtyInstruction::ClosePane. The handler in Pty is + // idempotent, so this is safe even if ClosePane was already sent. + let _ = screen + .bus + .senders + .send_to_pty(PtyInstruction::ClosePane(id, None)); + screen.log_and_report_session_state()?; screen.retain_only_existing_panes_in_pane_groups(); }, |
