diff options
author | Joe Wilm <joe@jwilm.com> | 2017-01-10 10:27:25 -0800 |
---|---|---|
committer | Joe Wilm <jwilm@users.noreply.github.com> | 2017-01-11 10:33:56 -0800 |
commit | a7fc46afce5e7eb7bd44749def28773c3211cab0 (patch) | |
tree | 1b1a79c285f5b2076ddf07fa6d90e6927f26fc48 /src/event_loop.rs | |
parent | dfb1b3bb5c5e9d9d9ee23f3f5bcc84fe6602392d (diff) | |
download | alacritty-a7fc46afce5e7eb7bd44749def28773c3211cab0.tar.gz alacritty-a7fc46afce5e7eb7bd44749def28773c3211cab0.zip |
Fix bug where event loop could get stuck reading
One symptom of this bug was being unable to send C-c during `cat
/dev/urandom`.
cc #271
Diffstat (limited to 'src/event_loop.rs')
-rw-r--r-- | src/event_loop.rs | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/src/event_loop.rs b/src/event_loop.rs index eb0b24b8..483490f0 100644 --- a/src/event_loop.rs +++ b/src/event_loop.rs @@ -163,9 +163,13 @@ impl<Io> EventLoop<Io> self.tx.clone() } - #[inline] - fn channel_event(&mut self, state: &mut State) { + // Drain the channel + // + // Returns true if items were received + fn drain_recv_channel(&self, state: &mut State) -> bool { + let mut received_item = false; while let Ok(msg) = self.rx.try_recv() { + received_item = true; match msg { Msg::Input(input) => { state.write_list.push_back(input); @@ -173,6 +177,13 @@ impl<Io> EventLoop<Io> } } + received_item + } + + #[inline] + fn channel_event(&mut self, state: &mut State) { + self.drain_recv_channel(state); + self.poll.reregister( &self.rx, CHANNEL, Ready::readable(), @@ -218,6 +229,20 @@ impl<Io> EventLoop<Io> if !terminal.dirty { self.display.notify(); terminal.dirty = true; + + // Break for writing + // + // Want to prevent case where reading always returns + // data and sequences like `C-c` cannot be sent. + // + // Doing this check in !terminal.dirty will prevent the + // condition from being checked overzealously. + if state.writing.is_some() + || !state.write_list.is_empty() + || self.drain_recv_channel(state) + { + break; + } } }, Err(err) => { |