aboutsummaryrefslogtreecommitdiff
path: root/alacritty_terminal/src/event_loop.rs
diff options
context:
space:
mode:
authorChristian Duerr <contact@christianduerr.com>2019-10-05 02:29:26 +0200
committerGitHub <noreply@github.com>2019-10-05 02:29:26 +0200
commit729eef0c933831bccfeac6a355bdb410787fbe5f (patch)
tree35cdf2e6427ad18bc53efbab4cab34a0af2054d7 /alacritty_terminal/src/event_loop.rs
parentb0c6fdff763f7271506d26d7e768e6377fdc691b (diff)
downloadalacritty-729eef0c933831bccfeac6a355bdb410787fbe5f.tar.gz
alacritty-729eef0c933831bccfeac6a355bdb410787fbe5f.zip
Update to winit/glutin EventLoop 2.0
This takes the latest glutin master to port Alacritty to the EventLoop 2.0 rework. This changes a big part of the event loop handling by pushing the event loop in a separate thread from the renderer and running both in parallel. Fixes #2796. Fixes #2694. Fixes #2643. Fixes #2625. Fixes #2618. Fixes #2601. Fixes #2564. Fixes #2456. Fixes #2438. Fixes #2334. Fixes #2254. Fixes #2217. Fixes #1789. Fixes #1750. Fixes #1125.
Diffstat (limited to 'alacritty_terminal/src/event_loop.rs')
-rw-r--r--alacritty_terminal/src/event_loop.rs103
1 files changed, 31 insertions, 72 deletions
diff --git a/alacritty_terminal/src/event_loop.rs b/alacritty_terminal/src/event_loop.rs
index 275d752c..ed78d79e 100644
--- a/alacritty_terminal/src/event_loop.rs
+++ b/alacritty_terminal/src/event_loop.rs
@@ -6,20 +6,22 @@ use std::io::{self, ErrorKind, Read, Write};
use std::marker::Send;
use std::sync::Arc;
-use mio::{self, Events, PollOpt, Ready};
-use mio_extras::channel::{self, Receiver, Sender};
-
+use log::error;
#[cfg(not(windows))]
use mio::unix::UnixReady;
+use mio::{self, Events, PollOpt, Ready};
+use mio_extras::channel::{self, Receiver, Sender};
use crate::ansi;
-use crate::display;
-use crate::event;
+use crate::event::{self, Event, EventListener};
use crate::sync::FairMutex;
use crate::term::Term;
use crate::tty;
use crate::util::thread;
+/// Max bytes to read from the PTY
+const MAX_READ: usize = 0x10_000;
+
/// Messages that may be sent to the `EventLoop`
#[derive(Debug)]
pub enum Msg {
@@ -34,13 +36,13 @@ pub enum Msg {
///
/// Handles all the pty I/O and runs the pty parser which updates terminal
/// state.
-pub struct EventLoop<T: tty::EventedPty> {
+pub struct EventLoop<T: tty::EventedPty, U: EventListener> {
poll: mio::Poll,
pty: T,
rx: Receiver<Msg>,
tx: Sender<Msg>,
- terminal: Arc<FairMutex<Term>>,
- display: display::Notifier,
+ terminal: Arc<FairMutex<Term<U>>>,
+ event_proxy: U,
ref_test: bool,
}
@@ -50,26 +52,6 @@ struct Writing {
written: usize,
}
-/// Indicates the result of draining the mio channel
-#[derive(Debug)]
-enum DrainResult {
- /// At least one new item was received
- ReceivedItem,
- /// Nothing was available to receive
- Empty,
- /// A shutdown message was received
- Shutdown,
-}
-
-impl DrainResult {
- pub fn is_shutdown(&self) -> bool {
- match *self {
- DrainResult::Shutdown => true,
- _ => false,
- }
- }
-}
-
/// All of the mutable state needed to run the event loop
///
/// Contains list of items to write, current write state, etc. Anything that
@@ -155,17 +137,18 @@ impl Writing {
}
}
-impl<T> EventLoop<T>
+impl<T, U> EventLoop<T, U>
where
T: tty::EventedPty + Send + 'static,
+ U: EventListener + Send + 'static,
{
/// Create a new event loop
pub fn new(
- terminal: Arc<FairMutex<Term>>,
- display: display::Notifier,
+ terminal: Arc<FairMutex<Term<U>>>,
+ event_proxy: U,
pty: T,
ref_test: bool,
- ) -> EventLoop<T> {
+ ) -> EventLoop<T, U> {
let (tx, rx) = channel::channel();
EventLoop {
poll: mio::Poll::new().expect("create mio Poll"),
@@ -173,7 +156,7 @@ where
tx,
rx,
terminal,
- display,
+ event_proxy,
ref_test,
}
}
@@ -184,33 +167,22 @@ where
// Drain the channel
//
- // Returns a `DrainResult` indicating the result of receiving from the channel
- //
- fn drain_recv_channel(&self, state: &mut State) -> DrainResult {
- let mut received_item = false;
+ // Returns `false` when a shutdown message was received.
+ fn drain_recv_channel(&self, state: &mut State) -> bool {
while let Ok(msg) = self.rx.try_recv() {
- received_item = true;
match msg {
- Msg::Input(input) => {
- state.write_list.push_back(input);
- },
- Msg::Shutdown => {
- return DrainResult::Shutdown;
- },
+ Msg::Input(input) => state.write_list.push_back(input),
+ Msg::Shutdown => return false,
}
}
- if received_item {
- DrainResult::ReceivedItem
- } else {
- DrainResult::Empty
- }
+ true
}
// Returns a `bool` indicating whether or not the event loop should continue running
#[inline]
fn channel_event(&mut self, token: mio::Token, state: &mut State) -> bool {
- if self.drain_recv_channel(state).is_shutdown() {
+ if !self.drain_recv_channel(state) {
return false;
}
@@ -231,13 +203,9 @@ where
where
X: Write,
{
- const MAX_READ: usize = 0x1_0000;
let mut processed = 0;
let mut terminal = None;
- // Flag to keep track if wakeup has already been sent
- let mut send_wakeup = false;
-
loop {
match self.pty.reader().read(&mut buf[..]) {
Ok(0) => break,
@@ -255,14 +223,10 @@ where
// Get reference to terminal. Lock is acquired on initial
// iteration and held until there's no bytes left to parse
// or we've reached MAX_READ.
- let terminal = if terminal.is_none() {
+ if terminal.is_none() {
terminal = Some(self.terminal.lock());
- let terminal = terminal.as_mut().unwrap();
- send_wakeup = !terminal.dirty;
- terminal
- } else {
- terminal.as_mut().unwrap()
- };
+ }
+ let terminal = terminal.as_mut().unwrap();
// Run the parser
for byte in &buf[..got] {
@@ -283,13 +247,8 @@ where
}
}
- // Only request a draw if one hasn't already been requested.
- if let Some(mut terminal) = terminal {
- if send_wakeup {
- self.display.notify();
- terminal.dirty = true;
- }
- }
+ // Queue terminal redraw
+ self.event_proxy.send_event(Event::Wakeup);
Ok(())
}
@@ -326,10 +285,10 @@ where
Ok(())
}
- pub fn spawn(mut self, state: Option<State>) -> thread::JoinHandle<(Self, State)> {
+ pub fn spawn(mut self) -> thread::JoinHandle<(Self, State)> {
thread::spawn_named("pty reader", move || {
- let mut state = state.unwrap_or_else(Default::default);
- let mut buf = [0u8; 0x1000];
+ let mut state = State::default();
+ let mut buf = [0u8; MAX_READ];
let mut tokens = (0..).map(Into::into);
@@ -369,7 +328,7 @@ where
token if token == self.pty.child_event_token() => {
if let Some(tty::ChildEvent::Exited) = self.pty.next_child_event() {
self.terminal.lock().exit();
- self.display.notify();
+ self.event_proxy.send_event(Event::Wakeup);
break 'event_loop;
}
},