diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ansi.rs | 8 | ||||
-rw-r--r-- | src/event.rs | 11 | ||||
-rw-r--r-- | src/main.rs | 16 | ||||
-rw-r--r-- | src/sync.rs | 69 | ||||
-rw-r--r-- | src/term.rs | 1 |
5 files changed, 25 insertions, 80 deletions
diff --git a/src/ansi.rs b/src/ansi.rs index 8a4a36af..48f79d2b 100644 --- a/src/ansi.rs +++ b/src/ansi.rs @@ -52,7 +52,7 @@ struct ProcessorState; /// Processor creates a Performer when running advance and passes the Performer /// to vte::Parser. struct Performer<'a, H: Handler + TermInfo + 'a> { - state: &'a mut ProcessorState, + _state: &'a mut ProcessorState, handler: &'a mut H } @@ -61,7 +61,7 @@ impl<'a, H: Handler + TermInfo + 'a> Performer<'a, H> { #[inline] pub fn new<'b>(state: &'b mut ProcessorState, handler: &'b mut H) -> Performer<'b, H> { Performer { - state: state, + _state: state, handler: handler } } @@ -648,9 +648,7 @@ impl<'a, H: Handler + TermInfo + 'a> vte::Perform for Performer<'a, H> { } #[inline] - fn esc_dispatch(&mut self, params: &[i64], intermediates: &[u8], ignore: bool, byte: u8) { - let private = intermediates.get(0).map(|b| *b == b'?').unwrap_or(false); - + fn esc_dispatch(&mut self, params: &[i64], intermediates: &[u8], _ignore: bool, byte: u8) { match byte { b'D' => self.handler.linefeed(), b'E' => self.handler.newline(), diff --git a/src/event.rs b/src/event.rs index bb5eebe0..303c6d8e 100644 --- a/src/event.rs +++ b/src/event.rs @@ -5,15 +5,14 @@ use std; use glutin; use input; -use sync::PriorityMutex; +use sync::FairMutex; use term::Term; -use tty::process_should_exit; /// The event processor pub struct Processor<'a, W: 'a> { writer: &'a mut W, input_processor: input::Processor, - terminal: Arc<PriorityMutex<Term>>, + terminal: Arc<FairMutex<Term>>, resize_tx: mpsc::Sender<(u32, u32)>, } @@ -25,7 +24,7 @@ impl<'a, W> Processor<'a, W> /// Takes a writer which is expected to be hooked up to the write end of a /// pty. pub fn new(writer: &mut W, - terminal: Arc<PriorityMutex<Term>>, + terminal: Arc<FairMutex<Term>>, resize_tx: mpsc::Sender<(u32, u32)>) -> Processor<W> { @@ -55,12 +54,12 @@ impl<'a, W> Processor<'a, W> glutin::Event::Resized(w, h) => { self.resize_tx.send((w, h)).expect("send new size"); // Acquire term lock - let mut terminal = self.terminal.lock_high(); + let mut terminal = self.terminal.lock(); terminal.dirty = true; }, glutin::Event::KeyboardInput(state, _code, key, mods) => { // Acquire term lock - let terminal = self.terminal.lock_high(); + let terminal = self.terminal.lock(); self.input_processor.process(state, key, mods, &mut input::WriteNotifier(self.writer), diff --git a/src/main.rs b/src/main.rs index 0b72c374..e520b08d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -56,12 +56,12 @@ mod sync; use std::sync::{mpsc, Arc}; use std::sync::atomic::{AtomicBool, Ordering}; -use parking_lot::{Condvar, Mutex, MutexGuard}; +use parking_lot::{MutexGuard}; use config::Config; use meter::Meter; use renderer::{QuadRenderer, GlyphCache}; -use sync::PriorityMutex; +use sync::FairMutex; use term::Term; use tty::process_should_exit; use util::thread; @@ -183,7 +183,7 @@ fn main() { let signal_flag = Flag::new(false); - let terminal = Arc::new(PriorityMutex::new(terminal)); + let terminal = Arc::new(FairMutex::new(terminal)); let window = Arc::new(window); let pty_reader = PtyReader::spawn( @@ -196,7 +196,6 @@ fn main() { // Wraps a renderer and gives simple draw() api. let mut display = Display::new( window.clone(), - terminal.clone(), renderer, glyph_cache, render_timer, @@ -212,7 +211,7 @@ fn main() { processor.process_events(&window); // Maybe draw the terminal - let terminal = terminal.lock_high(); + let terminal = terminal.lock(); signal_flag.set(false); if terminal.dirty { display.draw(terminal); @@ -231,7 +230,7 @@ fn main() { struct PtyReader; impl PtyReader { - pub fn spawn<R>(terminal: Arc<PriorityMutex<Term>>, + pub fn spawn<R>(terminal: Arc<FairMutex<Term>>, mut pty: R, proxy: ::glutin::WindowProxy, signal_flag: Flag) @@ -244,7 +243,7 @@ impl PtyReader { loop { if let Ok(got) = pty.read(&mut buf[..]) { - let mut terminal = terminal.lock_high(); + let mut terminal = terminal.lock(); for byte in &buf[..got] { pty_parser.advance(&mut *terminal, *byte); @@ -271,7 +270,6 @@ impl PtyReader { struct Display { window: Arc<glutin::Window>, - terminal_mutex: Arc<PriorityMutex<Term>>, renderer: QuadRenderer, glyph_cache: GlyphCache, render_timer: bool, @@ -281,7 +279,6 @@ struct Display { impl Display { pub fn new(window: Arc<glutin::Window>, - terminal_mutex: Arc<PriorityMutex<Term>>, renderer: QuadRenderer, glyph_cache: GlyphCache, render_timer: bool, @@ -290,7 +287,6 @@ impl Display { { Display { window: window, - terminal_mutex: terminal_mutex, renderer: renderer, glyph_cache: glyph_cache, render_timer: render_timer, diff --git a/src/sync.rs b/src/sync.rs index e341d78e..e314b7e8 100644 --- a/src/sync.rs +++ b/src/sync.rs @@ -14,81 +14,34 @@ //! Synchronization types //! -//! Most importantly, a priority mutex is included -use std::ops::{Deref, DerefMut}; - +//! Most importantly, a fair mutex is included use parking_lot::{Mutex, MutexGuard}; -/// A priority mutex -/// -/// A triple locking strategy is used where low priority locks must go through an additional mutex -/// to access the data. The gist is -/// -/// Low priority: lock low, lock next, lock data, unlock next, {do work}, unlock data, unlock low -/// High priority: lock next, lock data, unlock next, {do work}, unlock data +/// A fair mutex /// -/// By keeping the low lock active while working on data, a high priority consumer has immediate -/// access to the next mutex. -pub struct PriorityMutex<T> { +/// Uses an extra lock to ensure that if one thread is waiting that it will get +/// the lock before a single thread can re-lock it. +pub struct FairMutex<T> { /// Data data: Mutex<T>, /// Next-to-access next: Mutex<()>, - /// Low-priority access - low: Mutex<()>, -} - -/// Mutex guard for low priority locks -pub struct LowPriorityMutexGuard<'a, T: 'a> { - data: MutexGuard<'a, T>, - _low: MutexGuard<'a, ()>, } -impl<'a, T> Deref for LowPriorityMutexGuard<'a, T> { - type Target = T; - - #[inline] - fn deref(&self) -> &T { - self.data.deref() - } -} - -impl<'a, T> DerefMut for LowPriorityMutexGuard<'a, T> { - #[inline] - fn deref_mut(&mut self) -> &mut T { - self.data.deref_mut() - } -} - -impl<T> PriorityMutex<T> { - /// Create a new priority mutex - pub fn new(data: T) -> PriorityMutex<T> { - PriorityMutex { +impl<T> FairMutex<T> { + /// Create a new fair mutex + pub fn new(data: T) -> FairMutex<T> { + FairMutex { data: Mutex::new(data), next: Mutex::new(()), - low: Mutex::new(()), } } - /// Lock the mutex with high priority - pub fn lock_high(&self) -> MutexGuard<T> { + /// Lock the mutex + pub fn lock(&self) -> MutexGuard<T> { // Must bind to a temporary or the lock will be freed before going // into data.lock() let _next = self.next.lock(); self.data.lock() } - - /// Lock the mutex with low priority - pub fn lock_low(&self) -> LowPriorityMutexGuard<T> { - let low = self.low.lock(); - // Must bind to a temporary or the lock will be freed before going - // into data.lock() - let _next = self.next.lock(); - let data = self.data.lock(); - - LowPriorityMutexGuard { - data: data, - _low: low, - } - } } diff --git a/src/term.rs b/src/term.rs index 58f60b87..c209d4ad 100644 --- a/src/term.rs +++ b/src/term.rs @@ -456,7 +456,6 @@ impl ansi::Handler for Term { /// A character to be displayed #[inline] fn input(&mut self, c: char) { - debug_print!("{}; attrs = {:?}", c, self.attr); if self.cursor.col == self.grid.num_cols() { debug_println!("wrapping"); if (self.cursor.line + 1) >= self.scroll_region.end { |