Skip to content

Commit

Permalink
Make UnixTerminalWaker::wake non-blocking
Browse files Browse the repository at this point in the history
I was running `hg log --config pager.pager=sp` and pressing space without
releasing it. After about 10k lines sp appears to deadlock. It seems sp uses a
single thread for both reading terminal events and sending wake events and it
sends too many wake events without reading the events.

Failing to write to the wake pipe due to EWOULDBLOCK does not seem to be a
problem - there are enough events in the pipe to wake up the other side.
Therefore let's just make wake_pipe_write nonblocking and treat EWOULDBLOCK as
a success.

Context: The stuck thread looks like:

    #0  0x00007f32671ee237 in write () from /usr/lib/libc.so.6
    wezterm#1  0x000055c466022823 in std::sys::unix::fd::FileDesc::write () at src/libstd/sys/unix/fd.rs:96
    wezterm#2  std::sys::unix::net::Socket::write () at src/libstd/sys/unix/net.rs:276
    wezterm#3  <&std::sys::unix::ext::net::UnixStream as std::io::Write>::write ()
        at src/libstd/sys/unix/ext/net.rs:597
    wezterm#4  <std::sys::unix::ext::net::UnixStream as std::io::Write>::write ()
        at src/libstd/sys/unix/ext/net.rs:582
    wezterm#5  0x000055c465d010a6 in termwiz::terminal::unix::UnixTerminalWaker::wake (self=0x7ffe6bd32de0)
        at /home/quark/.cargo/git/checkouts/wezterm-6425bab852909cc8/ef1b836/termwiz/src/terminal/unix.rs:278
    wezterm#6  0x000055c465a6c64b in streampager::event::EventSender::send_unique (self=0x7ffe6bd32dd0, event=..., 
        unique=0x7ffe6bd32de8) at src/event.rs:66
    wezterm#7  0x000055c465a7e65a in streampager::display::start (term=..., term_caps=..., events=..., files=..., 
        error_files=..., progress=..., mode=streampager::config::FullScreenMode::Auto) at src/display.rs:295
    wezterm#8  0x000055c465a453a7 in streampager::Pager::run (self=...) at src/lib.rs:171
    wezterm#9  0x000055c465a0aced in sp::open_files (args=...) at src/bin/sp/main.rs:170
    wezterm#10 0x000055c465a08e4f in sp::main () at src/bin/sp/main.rs:25
  • Loading branch information
quark-zju authored Jan 6, 2020
1 parent f38e391 commit 1240de2
Showing 1 changed file with 8 additions and 2 deletions.
10 changes: 8 additions & 2 deletions termwiz/src/terminal/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ impl UnixTerminal {
sigwinch_pipe.set_nonblocking(true)?;
let (wake_pipe, wake_pipe_write) = UnixStream::pair()?;
wake_pipe.set_nonblocking(true)?;
wake_pipe_write.set_nonblocking(true)?;

read.set_blocking(Blocking::Wait)?;

Expand Down Expand Up @@ -275,8 +276,13 @@ pub struct UnixTerminalWaker {
impl UnixTerminalWaker {
pub fn wake(&self) -> Result<(), IoError> {
let mut pipe = self.pipe.lock().unwrap();
let _ = pipe.write(b"W")?;
Ok(())
match pipe.write(b"W") {
Err(e) => match e.kind() {
ErrorKind::WouldBlock => Ok(()),
_ => Err(e),
},
Ok(_) => Ok(()),
}
}
}

Expand Down

0 comments on commit 1240de2

Please # to comment.