Hopefully fix read not triggering draw

The terminal mutex is no longer released between event processing and
doing a draw. This may fix the race condition with data arriving but not
being displayed until a subsequent event.

cc #29
This commit is contained in:
Joe Wilm 2016-12-29 15:30:30 -05:00
parent 689e0f4ad7
commit d06360216d
2 changed files with 59 additions and 58 deletions

View File

@ -2,14 +2,15 @@
use std::borrow::Cow; use std::borrow::Cow;
use std::fs::File; use std::fs::File;
use std::io::Write; use std::io::Write;
use std::sync::{Arc, mpsc}; use std::sync::mpsc;
use serde_json as json;
use serde_json as json;
use parking_lot::MutexGuard;
use glutin::{self, ElementState}; use glutin::{self, ElementState};
use index::{Line, Column, Side};
use config::Config; use config::Config;
use display::OnResize; use display::OnResize;
use index::{Line, Column, Side};
use input::{self, ActionContext, MouseBinding, KeyBinding}; use input::{self, ActionContext, MouseBinding, KeyBinding};
use selection::Selection; use selection::Selection;
use sync::FairMutex; use sync::FairMutex;
@ -58,7 +59,6 @@ pub struct Processor<N> {
mouse_bindings: Vec<MouseBinding>, mouse_bindings: Vec<MouseBinding>,
notifier: N, notifier: N,
mouse: Mouse, mouse: Mouse,
terminal: Arc<FairMutex<Term>>,
resize_tx: mpsc::Sender<(u32, u32)>, resize_tx: mpsc::Sender<(u32, u32)>,
ref_test: bool, ref_test: bool,
size_info: SizeInfo, size_info: SizeInfo,
@ -81,21 +81,15 @@ impl<N: Notify> Processor<N> {
/// pty. /// pty.
pub fn new( pub fn new(
notifier: N, notifier: N,
terminal: Arc<FairMutex<Term>>,
resize_tx: mpsc::Sender<(u32, u32)>, resize_tx: mpsc::Sender<(u32, u32)>,
config: &Config, config: &Config,
ref_test: bool, ref_test: bool,
size_info: SizeInfo,
) -> Processor<N> { ) -> Processor<N> {
let size_info = {
let terminal = terminal.lock();
terminal.size_info().to_owned()
};
Processor { Processor {
key_bindings: config.key_bindings().to_vec(), key_bindings: config.key_bindings().to_vec(),
mouse_bindings: config.mouse_bindings().to_vec(), mouse_bindings: config.mouse_bindings().to_vec(),
notifier: notifier, notifier: notifier,
terminal: terminal,
resize_tx: resize_tx, resize_tx: resize_tx,
ref_test: ref_test, ref_test: ref_test,
mouse: Default::default(), mouse: Default::default(),
@ -176,13 +170,20 @@ impl<N: Notify> Processor<N> {
} }
/// Process at least one event and handle any additional queued events. /// Process at least one event and handle any additional queued events.
pub fn process_events(&mut self, window: &Window) -> bool { pub fn process_events<'a>(
&mut self,
term: &'a FairMutex<Term>,
window: &Window
) -> (MutexGuard<'a, Term>, bool) {
let mut wakeup_request = false; let mut wakeup_request = false;
// These are lazily initialized the first time an event is returned // Terminal is lazily initialized the first time an event is returned
// from the blocking WaitEventsIterator. Otherwise, the pty reader // from the blocking WaitEventsIterator. Otherwise, the pty reader would
// would be blocked the entire time we wait for input! // be blocked the entire time we wait for input!
let terminal; let terminal;
{
// Ditto on lazy initialization for context and processor.
let context; let context;
let mut processor: input::Processor<N>; let mut processor: input::Processor<N>;
@ -201,7 +202,7 @@ impl<N: Notify> Processor<N> {
match window.wait_events().next() { match window.wait_events().next() {
Some(event) => { Some(event) => {
terminal = self.terminal.lock(); terminal = term.lock();
context = ActionContext { context = ActionContext {
terminal: &terminal, terminal: &terminal,
notifier: &mut self.notifier, notifier: &mut self.notifier,
@ -225,8 +226,9 @@ impl<N: Notify> Processor<N> {
for event in window.poll_events() { for event in window.poll_events() {
process!(event); process!(event);
} }
}
wakeup_request (terminal, wakeup_request)
} }
pub fn update_config(&mut self, config: &Config) { pub fn update_config(&mut self, config: &Config) {

View File

@ -104,10 +104,10 @@ fn run(mut config: Config, options: cli::Options) -> Result<(), Box<Error>> {
// Need the Rc<RefCell<_>> here since a ref is shared in the resize callback // Need the Rc<RefCell<_>> here since a ref is shared in the resize callback
let mut processor = event::Processor::new( let mut processor = event::Processor::new(
event_loop::Notifier(loop_tx), event_loop::Notifier(loop_tx),
terminal.clone(),
display.resize_channel(), display.resize_channel(),
&config, &config,
options.ref_test, options.ref_test,
display.size().to_owned(),
); );
// Create a config monitor when config was loaded from path // Create a config monitor when config was loaded from path
@ -123,7 +123,7 @@ fn run(mut config: Config, options: cli::Options) -> Result<(), Box<Error>> {
// Main display loop // Main display loop
loop { loop {
// Process input and window events // Process input and window events
let wakeup_request = processor.process_events(display.window()); let (mut terminal, wakeup_request) = processor.process_events(&terminal, display.window());
// Handle config reloads // Handle config reloads
let config_updated = config_monitor.as_ref() let config_updated = config_monitor.as_ref()
@ -136,7 +136,6 @@ fn run(mut config: Config, options: cli::Options) -> Result<(), Box<Error>> {
}).unwrap_or(false); }).unwrap_or(false);
// Maybe draw the terminal // Maybe draw the terminal
let mut terminal = terminal.lock();
if wakeup_request || config_updated { if wakeup_request || config_updated {
// Handle pending resize events // Handle pending resize events
// //