1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-28 07:55:03 +03:00

use less cpu while idling

This does mean that we paint more frequently (basically after every
read from the pty), so our perf for large files is down.
This commit is contained in:
Wez Furlong 2018-02-22 01:15:28 -08:00
parent ac7d2a9cda
commit f6a95aafcf
2 changed files with 47 additions and 30 deletions

View File

@ -8,6 +8,7 @@ use glium::{self, glutin};
use glium::glutin::ElementState;
use opengl::render::Renderer;
use pty::MasterPty;
use std::io;
use std::io::{Read, Write};
use std::process::Child;
use std::process::Command;
@ -128,13 +129,17 @@ impl TerminalWindow {
Ok(())
}
pub fn handle_pty_readable_event(&mut self) -> Result<(), Error> {
pub fn try_read_pty(&mut self) -> Result<(), Error> {
const BUFSIZE: usize = 8192;
let mut buf = [0; BUFSIZE];
match self.host.pty.read(&mut buf) {
Ok(size) => self.terminal.advance_bytes(&buf[0..size], &mut self.host),
Err(err) => eprintln!("error reading from pty: {:?}", err),
Err(err) => {
if err.kind() != io::ErrorKind::WouldBlock {
eprintln!("error reading from pty: {:?}", err)
}
}
}
Ok(())
}
@ -434,6 +439,7 @@ impl TerminalWindow {
Err(TryRecvError::Disconnected) => bail!("clipboard thread died"),
}
self.try_read_pty()?;
self.test_for_child_exit()?;
}
_ => {}
@ -450,10 +456,7 @@ impl TerminalWindow {
Ok(Some(status)) => {
bail!("child exited: {}", status);
}
Ok(None) => {
println!("child still running");
Ok(())
}
Ok(None) => Ok(()),
Err(e) => {
bail!("failed to wait for child: {}", e);
}

View File

@ -31,11 +31,13 @@ extern crate xcb;
extern crate xcb_util;
use mio::{Events, Poll, PollOpt, Ready, Token};
use mio::unix::EventedFd;
use std::env;
use std::ffi::CStr;
use std::os::unix::io::AsRawFd;
use std::process::Command;
use std::str;
use std::time::Duration;
use std::thread;
mod config;
@ -78,12 +80,11 @@ fn run_glium(
initial_pixel_width: u16,
initial_pixel_height: u16,
) -> Result<(), Error> {
let poll = Poll::new()?;
poll.register(&master, Token(0), Ready::readable(), PollOpt::edge())?;
let mut events_loop = glium::glutin::EventsLoop::new();
sigchld::activate(events_loop.create_proxy())?;
let master_fd = master.as_raw_fd();
let mut window = gliumwindows::TerminalWindow::new(
&events_loop,
initial_pixel_width,
@ -98,31 +99,44 @@ fn run_glium(
.unwrap_or_else(term::color::ColorPalette::default),
)?;
let mut events = Events::with_capacity(8);
let mut done = false;
{
let proxy = events_loop.create_proxy();
thread::spawn(move || {
let poll = Poll::new().expect("mio Poll failed to init");
poll.register(
&EventedFd(&master_fd),
Token(0),
Ready::readable(),
PollOpt::edge(),
).expect("failed to register pty");
let mut events = Events::with_capacity(8);
loop {
if done {
break;
}
if poll.poll(&mut events, Some(Duration::new(0, 2000)))? != 0 {
for event in &events {
if event.token() == Token(0) && event.readiness().is_readable() {
window.handle_pty_readable_event()?;
loop {
match poll.poll(&mut events, None) {
Ok(_) => for event in &events {
if event.token() == Token(0) && event.readiness().is_readable() {
proxy.wakeup().expect("failed to wake event loop");
}
},
_ => {}
}
}
} else if window.need_paint() {
window.paint()?;
}
events_loop.poll_events(|event| match window.dispatch_event(event) {
Ok(_) => {}
Err(err) => {
eprintln!("{:?}", err);
done = true;
}
});
}
events_loop.run_forever(|event| match window.dispatch_event(event) {
Ok(_) => {
if window.need_paint() {
window.paint().expect("paint failed");
}
glium::glutin::ControlFlow::Continue
}
Err(err) => {
eprintln!("{:?}", err);
glium::glutin::ControlFlow::Break
}
});
Ok(())
}