Mercurial > hg
comparison rust/chg/src/uihandler.rs @ 44755:4b0185841058
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
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sat, 11 Apr 2020 02:51:03 +0900 |
parents | c794d0da5fb2 |
children | 27fe8cc1338f |
comparison
equal
deleted
inserted
replaced
44754:9fc9526e283a | 44755:4b0185841058 |
---|---|
7 use std::io; | 7 use std::io; |
8 use std::os::unix::io::AsRawFd; | 8 use std::os::unix::io::AsRawFd; |
9 use std::os::unix::process::ExitStatusExt; | 9 use std::os::unix::process::ExitStatusExt; |
10 use std::process::Stdio; | 10 use std::process::Stdio; |
11 use tokio; | 11 use tokio; |
12 use tokio::process::{ChildStdin, Command}; | 12 use tokio::process::{Child, ChildStdin, Command}; |
13 | 13 |
14 use crate::message::CommandSpec; | 14 use crate::message::CommandSpec; |
15 use crate::procutil; | 15 use crate::procutil; |
16 | 16 |
17 /// Callback to process shell command requests received from server. | 17 /// Callback to process shell command requests received from server. |
29 /// Returns command exit code (positive) or signal number (negative). | 29 /// Returns command exit code (positive) or signal number (negative). |
30 async fn run_system(&mut self, spec: &CommandSpec) -> io::Result<i32>; | 30 async fn run_system(&mut self, spec: &CommandSpec) -> io::Result<i32>; |
31 } | 31 } |
32 | 32 |
33 /// Default cHg implementation to process requests received from server. | 33 /// Default cHg implementation to process requests received from server. |
34 pub struct ChgUiHandler {} | 34 pub struct ChgUiHandler { |
35 pager: Option<Child>, | |
36 } | |
35 | 37 |
36 impl ChgUiHandler { | 38 impl ChgUiHandler { |
37 pub fn new() -> ChgUiHandler { | 39 pub fn new() -> ChgUiHandler { |
38 ChgUiHandler {} | 40 ChgUiHandler { pager: None } |
41 } | |
42 | |
43 /// Waits until the pager process exits. | |
44 pub async fn wait_pager(&mut self) -> io::Result<()> { | |
45 if let Some(p) = self.pager.take() { | |
46 p.await?; | |
47 } | |
48 Ok(()) | |
39 } | 49 } |
40 } | 50 } |
41 | 51 |
42 #[async_trait] | 52 #[async_trait] |
43 impl SystemHandler for ChgUiHandler { | 53 impl SystemHandler for ChgUiHandler { |
49 procutil::set_blocking_fd(pin.as_raw_fd())?; | 59 procutil::set_blocking_fd(pin.as_raw_fd())?; |
50 // TODO: if pager exits, notify the server with SIGPIPE immediately. | 60 // TODO: if pager exits, notify the server with SIGPIPE immediately. |
51 // otherwise the server won't get SIGPIPE if it does not write | 61 // otherwise the server won't get SIGPIPE if it does not write |
52 // anything. (issue5278) | 62 // anything. (issue5278) |
53 // kill(peerpid, SIGPIPE); | 63 // kill(peerpid, SIGPIPE); |
54 tokio::spawn(async { pager.await }); // just ignore errors | 64 self.pager = Some(pager); |
55 Ok(pin) | 65 Ok(pin) |
56 } | 66 } |
57 | 67 |
58 async fn run_system(&mut self, spec: &CommandSpec) -> io::Result<i32> { | 68 async fn run_system(&mut self, spec: &CommandSpec) -> io::Result<i32> { |
59 let status = new_shell_command(&spec).spawn()?.await?; | 69 let status = new_shell_command(&spec).spawn()?.await?; |