aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock6
-rw-r--r--Cargo.toml2
-rw-r--r--src/main.rs122
3 files changed, 98 insertions, 32 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 3c9f89f6..7b630691 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -7,7 +7,7 @@ dependencies = [
"errno 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"font 0.1.0",
"gl_generator 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "glutin 0.6.1 (git+https://github.com/jwilm/glutin?rev=45092a8e2f6706a7b2c613ff212341754e346c9c)",
+ "glutin 0.6.1 (git+https://github.com/jwilm/glutin?rev=16ed800f68022a37203434bd3b542ff5400c1403)",
"libc 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"notify 2.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -285,7 +285,7 @@ dependencies = [
[[package]]
name = "glutin"
version = "0.6.1"
-source = "git+https://github.com/jwilm/glutin?rev=45092a8e2f6706a7b2c613ff212341754e346c9c#45092a8e2f6706a7b2c613ff212341754e346c9c"
+source = "git+https://github.com/jwilm/glutin?rev=16ed800f68022a37203434bd3b542ff5400c1403#16ed800f68022a37203434bd3b542ff5400c1403"
dependencies = [
"android_glue 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -906,7 +906,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum gdi32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "65256ec4dc2592e6f05bfc1ca3b956a4e0698aa90b1dff1f5687d55a5a3fd59a"
"checksum gl_generator 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1d8edc81c5ae84605a62f5dac661a2313003b26d59839f81d47d46cf0f16a55"
"checksum gleam 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)" = "13a363b2a5264b600e530db2f14b3c487098e6dee0655f2810ea779385cbac5a"
-"checksum glutin 0.6.1 (git+https://github.com/jwilm/glutin?rev=45092a8e2f6706a7b2c613ff212341754e346c9c)" = "<none>"
+"checksum glutin 0.6.1 (git+https://github.com/jwilm/glutin?rev=16ed800f68022a37203434bd3b542ff5400c1403)" = "<none>"
"checksum heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "abb306abb8d398e053cfb1b3e7b72c2f580be048b85745c52652954f8ad1439c"
"checksum inotify 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e8458c07bdbdaf309c80e2c3304d14c3db64e7465d4f07cf589ccb83fd0ff31a"
"checksum itoa 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ae3088ea4baeceb0284ee9eea42f591226e6beaecf65373e41b38d95a1b8e7a1"
diff --git a/Cargo.toml b/Cargo.toml
index d556a26c..9e8f8b81 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,7 +13,7 @@ notify = "2.6"
bitflags = "*"
font = { path = "./font" }
errno = "0.1.6"
-parking_lot = "0.3.1"
+parking_lot = { version = "0.3.1", features = ["nightly"] }
serde = "0.8"
serde_yaml = "0.4"
serde_macros = "0.8"
diff --git a/src/main.rs b/src/main.rs
index 29201adf..5c1bca68 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -52,21 +52,45 @@ mod io;
mod sync;
use std::sync::{mpsc, Arc};
+use std::sync::atomic::{AtomicBool, Ordering};
-use sync::PriorityMutex;
+use parking_lot::{Condvar, Mutex};
use config::Config;
+use io::{Utf8Chars, Utf8CharsError};
use meter::Meter;
use renderer::{QuadRenderer, GlyphCache};
+use sync::PriorityMutex;
use term::Term;
use tty::process_should_exit;
use util::thread;
-use io::{Utf8Chars, Utf8CharsError};
-
/// Channel used by resize handling on mac
static mut resize_sender: Option<mpsc::Sender<(u32, u32)>> = None;
+struct Waiter {
+ mutex: Mutex<bool>,
+ cond: Condvar,
+}
+
+impl Waiter {
+ pub fn new() -> Waiter {
+ Waiter {
+ mutex: Mutex::new(false),
+ cond: Condvar::new(),
+ }
+ }
+
+ pub fn notify(&self) {
+ self.cond.notify_one();
+ }
+
+ pub fn wait(&self) {
+ let mut guard = self.mutex.lock();
+ self.cond.wait(&mut guard);
+ }
+}
+
/// Resize handling for Mac
fn window_resize_handler(width: u32, height: u32) {
unsafe {
@@ -126,6 +150,9 @@ fn main() {
let rasterizer = font::Rasterizer::new(dpi.x(), dpi.y(), dpr);
+ let waiter = Arc::new(Waiter::new());
+ let dirty = Arc::new(AtomicBool::new(false));
+
// Create renderer
let mut renderer = QuadRenderer::new(width, height);
@@ -163,7 +190,11 @@ fn main() {
let terminal = Arc::new(PriorityMutex::new(terminal));
- let pty_reader_thread = spawn_pty_reader(terminal.clone(), reader);
+ let pty_reader_thread = spawn_pty_reader(terminal.clone(),
+ reader,
+ waiter.clone(),
+ dirty.clone(),
+ window.create_window_proxy());
let window = Arc::new(window);
@@ -173,11 +204,15 @@ fn main() {
renderer,
glyph_cache,
render_timer,
- rx);
+ rx,
+ waiter.clone(),
+ dirty);
handle_window_events(&mut writer, terminal, window);
pty_reader_thread.join().ok();
+
+ waiter.notify();
render_thread.join().ok();
println!("Goodbye");
}
@@ -219,12 +254,23 @@ fn handle_window_events<W>(writer: &mut W,
&mut input::WriteNotifier(writer),
*terminal.mode())
},
+ glutin::Event::Awakened => {
+ if process_should_exit() {
+ println!("input thread exitting");
+ break;
+ }
+ }
_ => (),
}
+
}
}
-fn spawn_pty_reader<R>(terminal: Arc<PriorityMutex<Term>>, mut pty: R) -> std::thread::JoinHandle<()>
+fn spawn_pty_reader<R>(terminal: Arc<PriorityMutex<Term>>,
+ mut pty: R,
+ waiter: Arc<Waiter>,
+ dirty: Arc<AtomicBool>,
+ proxy: ::glutin::WindowProxy) -> std::thread::JoinHandle<()>
where R: std::io::Read + Send + 'static,
{
thread::spawn_named("pty reader", move || {
@@ -233,40 +279,51 @@ fn spawn_pty_reader<R>(terminal: Arc<PriorityMutex<Term>>, mut pty: R) -> std::t
let mut pty_parser = ansi::Parser::new();
loop {
- let got = pty.read(&mut buf[start..]).expect("pty fd active");
- let mut remain = 0;
+ 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();
- 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 `start` is nonzero, then actual bytes in buffer is > `got` by `start` bytes.
+ let end = start + got;
+ {
+ let mut terminal = terminal.lock_low();
+ 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),
+ }
+ }
}
}
- }
- // Move any leftover bytes to front of buffer
- for i in 0..remain {
- buf[i] = buf[end - (remain - i)];
+ dirty.store(true, Ordering::Release);
+ waiter.notify();
+
+ // Move any leftover bytes to front of buffer
+ for i in 0..remain {
+ buf[i] = buf[end - (remain - i)];
+ }
+ start = remain;
+ } else {
+ proxy.wakeup_event_loop();
+ break;
}
- start = remain;
}
})
}
fn spawn_renderer(window: Arc<glutin::Window>,
- terminal: Arc<PriorityMutex<Term>>,
+ terminal_mutex: Arc<PriorityMutex<Term>>,
mut renderer: QuadRenderer,
mut glyph_cache: GlyphCache,
render_timer: bool,
- rx: mpsc::Receiver<(u32, u32)>) -> std::thread::JoinHandle<()> {
+ rx: mpsc::Receiver<(u32, u32)>,
+ waiter: Arc<Waiter>,
+ dirty: Arc<AtomicBool>) -> std::thread::JoinHandle<()> {
thread::spawn_named("render", move || {
unsafe {
let _ = window.make_current();
@@ -277,7 +334,15 @@ fn spawn_renderer(window: Arc<glutin::Window>,
// Scope ensures terminal lock isn't held when calling swap_buffers
{
// Acquire term lock
- let mut terminal = terminal.lock_high();
+ let mut terminal = terminal_mutex.lock_high();
+
+ if !dirty.load(Ordering::Acquire) {
+ drop(terminal);
+ waiter.wait();
+ terminal = terminal_mutex.lock_high();
+ }
+
+ dirty.store(false, Ordering::Release);
// Resize events new_size and are handled outside the poll_events
// iterator. This has the effect of coalescing multiple resize
@@ -328,6 +393,7 @@ fn spawn_renderer(window: Arc<glutin::Window>,
if process_should_exit() {
break;
+ } else {
}
}
})