rust-chg: do not terminate tokio runtime until pager exits
We no longer need to spawn a task just to keep the pager handle. The pager
handle can be held by ChgUiHandler since the handler itself is not consumed
and recreated across async calls.
Differential Revision: https://phab.mercurial-scm.org/D8449
--- a/rust/chg/src/main.rs Sat Apr 11 02:21:06 2020 +0900
+++ b/rust/chg/src/main.rs Sat Apr 11 02:51:03 2020 +0900
@@ -83,5 +83,6 @@
.run_command_chg(&mut handler, env::args_os().skip(1))
.await?;
procutil::restore_signal_handler_once()?;
+ handler.wait_pager().await?;
Ok(code)
}
--- a/rust/chg/src/uihandler.rs Sat Apr 11 02:21:06 2020 +0900
+++ b/rust/chg/src/uihandler.rs Sat Apr 11 02:51:03 2020 +0900
@@ -9,7 +9,7 @@
use std::os::unix::process::ExitStatusExt;
use std::process::Stdio;
use tokio;
-use tokio::process::{ChildStdin, Command};
+use tokio::process::{Child, ChildStdin, Command};
use crate::message::CommandSpec;
use crate::procutil;
@@ -31,11 +31,21 @@
}
/// Default cHg implementation to process requests received from server.
-pub struct ChgUiHandler {}
+pub struct ChgUiHandler {
+ pager: Option<Child>,
+}
impl ChgUiHandler {
pub fn new() -> ChgUiHandler {
- ChgUiHandler {}
+ ChgUiHandler { pager: None }
+ }
+
+ /// Waits until the pager process exits.
+ pub async fn wait_pager(&mut self) -> io::Result<()> {
+ if let Some(p) = self.pager.take() {
+ p.await?;
+ }
+ Ok(())
}
}
@@ -51,7 +61,7 @@
// otherwise the server won't get SIGPIPE if it does not write
// anything. (issue5278)
// kill(peerpid, SIGPIPE);
- tokio::spawn(async { pager.await }); // just ignore errors
+ self.pager = Some(pager);
Ok(pin)
}