From b3cdd2ccff82d0a3d2e33171e22838402f8f3f79 Mon Sep 17 00:00:00 2001 From: Bennet Bo Fenner Date: Wed, 2 Oct 2024 13:21:19 +0200 Subject: [PATCH] ssh remoting: Fix ssh process not being cleaned up when connection is closed (#18623) We introduced a memory leak in #18572, which meant that `Drop` was never called on `SshRemoteConnection`, meaning that the ssh process kept running Co-Authored-by: Thorsten Release Notes: - N/A --------- Co-authored-by: Thorsten --- crates/remote/src/ssh_session.rs | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/crates/remote/src/ssh_session.rs b/crates/remote/src/ssh_session.rs index fe1e42fe96..6bca9938ba 100644 --- a/crates/remote/src/ssh_session.rs +++ b/crates/remote/src/ssh_session.rs @@ -31,7 +31,7 @@ use std::{ path::{Path, PathBuf}, sync::{ atomic::{AtomicU32, Ordering::SeqCst}, - Arc, + Arc, Weak, }, time::Instant, }; @@ -244,12 +244,12 @@ struct SshRemoteClientState { ssh_connection: SshRemoteConnection, delegate: Arc, forwarder: ChannelForwarder, - _multiplex_task: Task>, + multiplex_task: Task>, } pub struct SshRemoteClient { client: Arc, - inner_state: Arc>>, + inner_state: Mutex>, } impl SshRemoteClient { @@ -264,7 +264,7 @@ impl SshRemoteClient { let client = cx.update(|cx| ChannelClient::new(incoming_rx, outgoing_tx, cx))?; let this = Arc::new(Self { client, - inner_state: Arc::new(Mutex::new(None)), + inner_state: Mutex::new(None), }); let inner_state = { @@ -276,7 +276,7 @@ impl SshRemoteClient { .await?; let multiplex_task = Self::multiplex( - this.clone(), + Arc::downgrade(&this), ssh_process, proxy_incoming_tx, proxy_outgoing_rx, @@ -287,7 +287,7 @@ impl SshRemoteClient { ssh_connection, delegate, forwarder: proxy, - _multiplex_task: multiplex_task, + multiplex_task, } }; @@ -305,9 +305,9 @@ impl SshRemoteClient { mut ssh_connection, delegate, forwarder: proxy, - _multiplex_task, + multiplex_task, } = state; - drop(_multiplex_task); + drop(multiplex_task); cx.spawn(|mut cx| async move { let (incoming_tx, outgoing_rx) = proxy.into_channels().await; @@ -331,8 +331,8 @@ impl SshRemoteClient { ssh_connection, delegate, forwarder: proxy, - _multiplex_task: Self::multiplex( - this.clone(), + multiplex_task: Self::multiplex( + Arc::downgrade(&this), ssh_process, proxy_incoming_tx, proxy_outgoing_rx, @@ -349,7 +349,7 @@ impl SshRemoteClient { } fn multiplex( - this: Arc, + this: Weak, mut ssh_process: Child, incoming_tx: UnboundedSender, mut outgoing_rx: UnboundedReceiver, @@ -444,7 +444,9 @@ impl SshRemoteClient { if let Err(error) = result { log::warn!("ssh io task died with error: {:?}. reconnecting...", error); - Self::reconnect(this, &mut cx).ok(); + if let Some(this) = this.upgrade() { + Self::reconnect(this, &mut cx).ok(); + } } Ok(()) @@ -516,7 +518,7 @@ impl SshRemoteClient { let client = ChannelClient::new(server_to_client_rx, client_to_server_tx, cx); Arc::new(Self { client, - inner_state: Arc::new(Mutex::new(None)), + inner_state: Mutex::new(None), }) }), server_cx.update(|cx| ChannelClient::new(client_to_server_rx, server_to_client_tx, cx)),