1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-24 05:42:03 +03:00

mux: workaround a spurious panic notification with ssh connections

The issue is that when we start the proxy mode up, we haven't set
up a frontend, and the ssh client wants to kick off a non-essential
task via the executor.

This commit starts up a null frontend in proxy mode so that that
machinery is present.

Then, because we don't register any tabs with the mux, we need to
adjust the behavior of the null frontend to not terminate when
the mux has no tabs.

It's a little gross.
This commit is contained in:
Wez Furlong 2020-01-05 14:06:19 -08:00
parent 624c7234e4
commit 94b78a47c8
2 changed files with 30 additions and 5 deletions

View File

@ -33,6 +33,9 @@ impl Executor for MuxExecutor {
pub struct MuxServerFrontEnd {
tx: Sender<SpawnFunc>,
rx: Receiver<SpawnFunc>,
/// Indicates if we're the null frontend or not.
/// If so, our termination behavior is altered.
is_null: bool,
}
impl MuxServerFrontEnd {
@ -43,7 +46,8 @@ impl MuxServerFrontEnd {
if start_listener {
spawn_listener()?;
}
Ok(Rc::new(Self { tx, rx }))
let is_null = !start_listener;
Ok(Rc::new(Self { tx, rx, is_null }))
}
pub fn try_new() -> Result<Rc<dyn FrontEnd>, Error> {
@ -73,7 +77,7 @@ impl FrontEnd for MuxServerFrontEnd {
Err(err) => bail!("while waiting for events: {:?}", err),
}
if Mux::get().unwrap().is_empty() {
if !self.is_null && Mux::get().unwrap().is_empty() {
info!("No more tabs; all done!");
return Ok(());
}

View File

@ -760,6 +760,9 @@ fn run() -> anyhow::Result<()> {
// ourselves into basically netcat.
drop(client);
let front_end = FrontEndSelection::Null.try_new()?;
let mux = Rc::new(mux::Mux::new(None));
Mux::set_mux(&mux);
let unix_dom = config.unix_domains.first().unwrap();
let sock_path = unix_dom.socket_path();
let stream = unix_connect_with_retry(&sock_path)?;
@ -769,12 +772,24 @@ fn run() -> anyhow::Result<()> {
let duped = stream.try_clone()?;
std::thread::spawn(move || {
let stdout = std::io::stdout();
consume_stream(duped, stdout.lock()).ok();
consume_stream_then_exit_process(duped, stdout.lock());
});
// and pull data from stdin and write it to the socket
let stdin = std::io::stdin();
consume_stream(stdin.lock(), stream)?;
std::thread::spawn(move || {
let stdin = std::io::stdin();
consume_stream_then_exit_process(stdin.lock(), stream);
});
// This is a bit gross; we run a Null frontend while we
// manage our streams to avoid a panic with some code
// that spawns some background processing via the executors.
// However, since we don't register any domains, and the
// threads we spawn above to consume the streams are not
// associated with the mux layer, this call to run_forever
// really will run forever.
// For that reason, we've arranged for the threads above
// to exit the process if they run out of data to consume.
front_end.run_forever()?;
}
}
Ok(())
@ -795,3 +810,9 @@ fn consume_stream<F: Read, T: Write>(mut from_stream: F, mut to_stream: T) -> an
}
Ok(())
}
fn consume_stream_then_exit_process<F: Read, T: Write>(from_stream: F, to_stream: T) -> ! {
consume_stream(from_stream, to_stream).ok();
std::thread::sleep(std::time::Duration::new(2, 0));
std::process::exit(0);
}