aboutsummaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs89
1 files changed, 52 insertions, 37 deletions
diff --git a/src/main.rs b/src/main.rs
index c0685204..a803d05c 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -31,6 +31,7 @@ extern crate notify;
extern crate parking_lot;
extern crate serde;
extern crate serde_yaml;
+extern crate vte;
#[macro_use]
extern crate bitflags;
@@ -49,7 +50,6 @@ mod tty;
pub mod ansi;
mod term;
mod util;
-mod io;
mod sync;
use std::sync::{mpsc, Arc};
@@ -58,7 +58,6 @@ use std::sync::atomic::{AtomicBool, Ordering};
use parking_lot::{Condvar, Mutex, MutexGuard};
use config::Config;
-use io::{Utf8Chars, Utf8CharsError};
use meter::Meter;
use renderer::{QuadRenderer, GlyphCache};
use sync::PriorityMutex;
@@ -69,6 +68,24 @@ use util::thread;
/// Channel used by resize handling on mac
static mut resize_sender: Option<mpsc::Sender<(u32, u32)>> = None;
+#[derive(Clone)]
+struct Flag(Arc<AtomicBool>);
+impl Flag {
+ pub fn new(initial_value: bool) -> Flag {
+ Flag(Arc::new(AtomicBool::new(initial_value)))
+ }
+
+ #[inline]
+ pub fn get(&self) -> bool {
+ self.0.load(Ordering::Acquire)
+ }
+
+ #[inline]
+ pub fn set(&self, value: bool) {
+ self.0.store(value, Ordering::Release)
+ }
+}
+
/// Resize handling for Mac
fn window_resize_handler(width: u32, height: u32) {
unsafe {
@@ -163,18 +180,27 @@ fn main() {
resize_sender = Some(tx.clone());
}
+ let signal_flag = Flag::new(false);
+
let terminal = Arc::new(PriorityMutex::new(terminal));
let window = Arc::new(window);
- let pty_reader = PtyReader::spawn(terminal.clone(), reader, window.create_window_proxy());
+ let pty_reader = PtyReader::spawn(
+ terminal.clone(),
+ reader,
+ window.create_window_proxy(),
+ signal_flag.clone()
+ );
// Wraps a renderer and gives simple draw() api.
- let mut display = Display::new(window.clone(),
- terminal.clone(),
- renderer,
- glyph_cache,
- render_timer,
- rx);
+ let mut display = Display::new(
+ window.clone(),
+ terminal.clone(),
+ renderer,
+ glyph_cache,
+ render_timer,
+ rx
+ );
// Event processor
let mut processor = event::Processor::new(&mut writer, terminal.clone(), tx);
@@ -184,6 +210,8 @@ fn main() {
// Wait for something to happen
processor.process_events(&window);
+ signal_flag.set(false);
+
// Maybe draw the terminal
let terminal = terminal.lock_high();
if terminal.dirty {
@@ -205,45 +233,32 @@ struct PtyReader;
impl PtyReader {
pub fn spawn<R>(terminal: Arc<PriorityMutex<Term>>,
mut pty: R,
- proxy: ::glutin::WindowProxy)
+ proxy: ::glutin::WindowProxy,
+ signal_flag: Flag)
-> std::thread::JoinHandle<()>
where R: std::io::Read + Send + 'static
{
thread::spawn_named("pty reader", move || {
let mut buf = [0u8; 4096];
- let mut start = 0;
- let mut pty_parser = ansi::Parser::new();
+ let mut pty_parser = ansi::Processor::new();
loop {
- if let Ok(got) = pty.read(&mut buf[start..]) {
- let mut remain = 0;
-
- // if `start` is nonzero, then actual bytes in buffer is > `got` by `start` bytes.
- let end = start + got;
- {
- let mut terminal = terminal.lock_low();
- terminal.dirty = true;
- for c in Utf8Chars::new(&buf[..end]) {
- match c {
- Ok(c) => pty_parser.advance(&mut *terminal, c),
- Err(err) => match err {
- Utf8CharsError::IncompleteUtf8(unused) => {
- remain = unused;
- break;
- },
- _ => panic!("{}", err),
- }
- }
- }
+ if let Ok(got) = pty.read(&mut buf[..]) {
+ let mut terminal = terminal.lock_high();
+
+ for byte in &buf[..got] {
+ pty_parser.advance(&mut *terminal, *byte);
}
- proxy.wakeup_event_loop();
+ terminal.dirty = true;
- // Move any leftover bytes to front of buffer
- for i in 0..remain {
- buf[i] = buf[end - (remain - i)];
+ // Only wake up the event loop if it hasn't already been signaled. This is a
+ // really important optimization because waking up the event loop redundantly
+ // burns *a lot* of cycles.
+ if !signal_flag.get() {
+ proxy.wakeup_event_loop();
+ signal_flag.set(true);
}
- start = remain;
} else {
break;
}