mirror of
https://github.com/wez/wezterm.git
synced 2024-12-23 13:21:38 +03:00
poll the client tab asynchronously
Restructure the poll routine so that we don't block the gui thread while we wait for the render data to be returned from the server.
This commit is contained in:
parent
036ff424f0
commit
99d6c12532
@ -199,6 +199,16 @@ impl<T: Send + 'static> Future<T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_ready(&self) -> bool {
|
||||
match &self.state {
|
||||
FutureState::Waiting(core) => {
|
||||
let locked = core.data.lock().unwrap();
|
||||
locked.result.is_some()
|
||||
}
|
||||
FutureState::Ready(_) => true,
|
||||
}
|
||||
}
|
||||
|
||||
/// When this future resolves, then map the result via the
|
||||
/// supplied lambda, which returns something that is convertible
|
||||
/// to a Future.
|
||||
|
@ -63,8 +63,23 @@ fn client_thread_inner(
|
||||
) -> Fallible<()> {
|
||||
let mut next_serial = 0u64;
|
||||
loop {
|
||||
match rx.try_recv() {
|
||||
Ok(msg) => match msg {
|
||||
let msg = if promises.is_empty() {
|
||||
// If we don't have any results to read back, then we can and
|
||||
// should block on an incoming request, otherwise we'll busy
|
||||
// wait in this loop
|
||||
match rx.recv() {
|
||||
Ok(msg) => Some(msg),
|
||||
Err(err) => bail!("Client was destroyed: {}", err),
|
||||
}
|
||||
} else {
|
||||
match rx.try_recv() {
|
||||
Ok(msg) => Some(msg),
|
||||
Err(TryRecvError::Empty) => None,
|
||||
Err(TryRecvError::Disconnected) => bail!("Client was destroyed"),
|
||||
}
|
||||
};
|
||||
if let Some(msg) = msg {
|
||||
match msg {
|
||||
ReaderMessage::SendPdu { pdu, promise } => {
|
||||
let serial = next_serial;
|
||||
next_serial += 1;
|
||||
@ -73,9 +88,7 @@ fn client_thread_inner(
|
||||
pdu.encode(&mut stream, serial)?;
|
||||
stream.flush()?;
|
||||
}
|
||||
},
|
||||
Err(TryRecvError::Empty) => {}
|
||||
Err(TryRecvError::Disconnected) => bail!("Client was destroyed"),
|
||||
}
|
||||
}
|
||||
|
||||
if !promises.is_empty() {
|
||||
|
@ -7,6 +7,7 @@ use failure::Fallible;
|
||||
use filedescriptor::Pipe;
|
||||
use log::error;
|
||||
use portable_pty::PtySize;
|
||||
use promise::Future;
|
||||
use std::cell::RefCell;
|
||||
use std::cell::RefMut;
|
||||
use std::ops::Range;
|
||||
@ -41,6 +42,7 @@ impl ClientTab {
|
||||
last_poll: RefCell::new(Instant::now()),
|
||||
dirty_all: RefCell::new(true),
|
||||
dead: RefCell::new(false),
|
||||
poll_future: RefCell::new(None),
|
||||
};
|
||||
|
||||
let reader = Pipe::new().expect("Pipe::new failed");
|
||||
@ -157,12 +159,32 @@ struct RenderableState {
|
||||
last_poll: RefCell<Instant>,
|
||||
dirty_all: RefCell<bool>,
|
||||
dead: RefCell<bool>,
|
||||
poll_future: RefCell<Option<Future<GetCoarseTabRenderableDataResponse>>>,
|
||||
}
|
||||
|
||||
const POLL_INTERVAL: Duration = Duration::from_millis(50);
|
||||
|
||||
impl RenderableState {
|
||||
fn poll(&self) -> Fallible<()> {
|
||||
let ready = self
|
||||
.poll_future
|
||||
.borrow()
|
||||
.as_ref()
|
||||
.map(Future::is_ready)
|
||||
.unwrap_or(false);
|
||||
if ready {
|
||||
let coarse = self.poll_future.borrow_mut().take().unwrap().wait()?;
|
||||
self.coarse.borrow_mut().replace(coarse);
|
||||
log::trace!(
|
||||
"poll: got coarse data in {:?}",
|
||||
self.last_poll.borrow().elapsed()
|
||||
);
|
||||
*self.last_poll.borrow_mut() = Instant::now();
|
||||
} else if self.poll_future.borrow().is_some() {
|
||||
// We have a poll in progress
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let dirty_all = *self.dirty_all.borrow();
|
||||
|
||||
if !dirty_all {
|
||||
@ -174,15 +196,13 @@ impl RenderableState {
|
||||
|
||||
{
|
||||
let mut client = self.client.client.lock().unwrap();
|
||||
let coarse = client
|
||||
.get_coarse_tab_renderable_data(GetCoarseTabRenderableData {
|
||||
*self.poll_future.borrow_mut() = Some(client.get_coarse_tab_renderable_data(
|
||||
GetCoarseTabRenderableData {
|
||||
tab_id: self.remote_tab_id,
|
||||
dirty_all,
|
||||
})
|
||||
.wait()?;
|
||||
self.coarse.borrow_mut().replace(coarse);
|
||||
},
|
||||
));
|
||||
}
|
||||
*self.last_poll.borrow_mut() = Instant::now();
|
||||
*self.dirty_all.borrow_mut() = false;
|
||||
Ok(())
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user