aboutsummaryrefslogtreecommitdiff
path: root/src/platform/unix_common.rs
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-09-08 00:35:48 +0300
committerGitHub <noreply@github.com>2026-09-08 00:35:48 +0300
commit62431dbd033bf1be2fe87fbc526df28084214e49 (patch)
treebc9a9038ee718e0373f6eb08ebd78240f2524ead /src/platform/unix_common.rs
parenta9f3ad5fd4fdbb9bf6b422532f516114ce23ed10 (diff)
fix: reduce idle ssh cpu without dropping final output (#3728)
* fix: stop polling idle ssh uploads on unix * fix: preserve ssh output during idle bridge cancellation * test: exercise active ssh upload cancellation
Diffstat (limited to 'src/platform/unix_common.rs')
-rw-r--r--src/platform/unix_common.rs44
1 files changed, 44 insertions, 0 deletions
diff --git a/src/platform/unix_common.rs b/src/platform/unix_common.rs
index 104f6b69..0df215d6 100644
--- a/src/platform/unix_common.rs
+++ b/src/platform/unix_common.rs
@@ -27,6 +27,50 @@ pub(crate) fn wait_client_stream_readable(stream: &crate::ipc::LocalStream) -> s
Ok(())
}
+pub(crate) struct RemoteBridgeWake {
+ reader: std::os::unix::net::UnixStream,
+ writer: std::os::unix::net::UnixStream,
+}
+
+impl RemoteBridgeWake {
+ pub(crate) fn new() -> std::io::Result<Self> {
+ let (reader, writer) = std::os::unix::net::UnixStream::pair()?;
+ Ok(Self { reader, writer })
+ }
+
+ pub(crate) fn cancel(&self) -> std::io::Result<()> {
+ // EOF stays readable, including when cancellation precedes the wait.
+ self.writer.shutdown(std::net::Shutdown::Write)
+ }
+
+ pub(crate) fn wait(&self, stream: &crate::ipc::LocalStream) -> std::io::Result<()> {
+ use std::os::fd::{AsFd as _, AsRawFd as _};
+ let crate::ipc::LocalStream::UdSocket(stream) = stream;
+ let mut descriptors = [
+ libc::pollfd {
+ fd: stream.as_fd().as_raw_fd(),
+ events: libc::POLLIN,
+ revents: 0,
+ },
+ libc::pollfd {
+ fd: self.reader.as_raw_fd(),
+ events: libc::POLLIN,
+ revents: 0,
+ },
+ ];
+ loop {
+ // SAFETY: both descriptors remain borrowed and the array has two entries.
+ if unsafe { libc::poll(descriptors.as_mut_ptr(), 2, -1) } >= 0 {
+ return Ok(());
+ }
+ let error = std::io::Error::last_os_error();
+ if error.kind() != std::io::ErrorKind::Interrupted {
+ return Err(error);
+ }
+ }
+ }
+}
+
pub(super) fn read_terminal_grid_size() -> std::io::Result<(u16, u16)> {
crossterm::terminal::window_size().map(|size| (size.columns, size.rows))
}