From 6413886760b8d1c931267f6355ea7726bafc2ea9 Mon Sep 17 00:00:00 2001 From: Joe Grund Date: Tue, 18 Oct 2022 16:41:38 -0400 Subject: [PATCH] Implement detached signal sender Allow signals to be sent detached from the channel struct. This is done using a higher-order function and by cloning the sender so it can be used independently of the `Channel`. This is useful to be able to spawn a cancelation handler separately from the main `Channel` recieve loop. Signed-off-by: Joe Grund --- russh/src/channels.rs | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/russh/src/channels.rs b/russh/src/channels.rs index 227d0e1c..7798b47d 100644 --- a/russh/src/channels.rs +++ b/russh/src/channels.rs @@ -1,3 +1,6 @@ +use std::pin::Pin; + +use futures::{Future, FutureExt}; use russh_cryptovec::CryptoVec; use tokio::sync::mpsc::{Sender, UnboundedReceiver}; @@ -114,7 +117,7 @@ impl> std::fmt::Debug for Channel { } } -impl> Channel { +impl + std::marker::Send + 'static> Channel { pub fn id(&self) -> ChannelId { self.id } @@ -174,11 +177,33 @@ impl> Channel { } /// Signal a remote process. - pub async fn signal(&mut self, signal: Sig) -> Result<(), Error> { + pub async fn signal(self, signal: Sig) -> Result<(), Error> { self.send_msg(ChannelMsg::Signal { signal }).await?; + Ok(()) } + /// Get a `FnOnce` that can be used to send a signal through this channel + pub fn get_signal_sender( + &self, + ) -> impl FnOnce(Sig) -> Pin> + std::marker::Send>> + { + let sender = self.sender.clone(); + let id = self.id; + + move |signal| { + async move { + sender + .send((id, ChannelMsg::Signal { signal }).into()) + .await + .map_err(|_| Error::SendError)?; + + Ok(()) + } + .boxed() + } + } + /// Request the start of a subsystem with the given name. pub async fn request_subsystem>( &mut self,