aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Wilm <joe@jwilm.com>2017-01-10 10:27:25 -0800
committerJoe Wilm <jwilm@users.noreply.github.com>2017-01-11 10:33:56 -0800
commita7fc46afce5e7eb7bd44749def28773c3211cab0 (patch)
tree1b1a79c285f5b2076ddf07fa6d90e6927f26fc48
parentdfb1b3bb5c5e9d9d9ee23f3f5bcc84fe6602392d (diff)
downloadalacritty-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
-rw-r--r--src/event_loop.rs29
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) => {