mirror of
https://github.com/wez/wezterm.git
synced 2024-11-23 15:04:36 +03:00
parent
b3032f8a5a
commit
06da330087
@ -57,11 +57,28 @@ impl Executor for GuiExecutor {
|
||||
}
|
||||
}
|
||||
|
||||
struct LowPriGuiExecutor {}
|
||||
impl BasicExecutor for LowPriGuiExecutor {
|
||||
fn execute(&self, f: SpawnFunc) {
|
||||
Connection::low_pri_executor().execute(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl Executor for LowPriGuiExecutor {
|
||||
fn clone_executor(&self) -> Box<dyn Executor> {
|
||||
Box::new(Self {})
|
||||
}
|
||||
}
|
||||
|
||||
impl FrontEnd for GuiFrontEnd {
|
||||
fn executor(&self) -> Box<dyn Executor> {
|
||||
Box::new(GuiExecutor {})
|
||||
}
|
||||
|
||||
fn low_pri_executor(&self) -> Box<dyn Executor> {
|
||||
Box::new(GuiExecutor {})
|
||||
}
|
||||
|
||||
fn run_forever(&self) -> Fallible<()> {
|
||||
// We run until we've run out of windows in the Mux.
|
||||
// When we're running ssh we have a transient window
|
||||
|
@ -30,6 +30,7 @@ impl Default for FrontEndSelection {
|
||||
|
||||
lazy_static! {
|
||||
static ref EXECUTOR: Mutex<Option<Box<dyn Executor>>> = Mutex::new(None);
|
||||
static ref LOW_PRI_EXECUTOR: Mutex<Option<Box<dyn Executor>>> = Mutex::new(None);
|
||||
}
|
||||
thread_local! {
|
||||
static FRONT_END: RefCell<Option<Rc<dyn FrontEnd>>> = RefCell::new(None);
|
||||
@ -43,6 +44,14 @@ pub fn executor() -> Box<dyn Executor> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn low_pri_executor() -> Box<dyn Executor> {
|
||||
let locked = LOW_PRI_EXECUTOR.lock().unwrap();
|
||||
match locked.as_ref() {
|
||||
Some(exec) => exec.clone_executor(),
|
||||
None => panic!("executor machinery not yet configured"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn front_end() -> Option<Rc<dyn FrontEnd>> {
|
||||
let mut res = None;
|
||||
FRONT_END.with(|f| {
|
||||
@ -63,6 +72,10 @@ impl FrontEndSelection {
|
||||
}?;
|
||||
|
||||
EXECUTOR.lock().unwrap().replace(front_end.executor());
|
||||
LOW_PRI_EXECUTOR
|
||||
.lock()
|
||||
.unwrap()
|
||||
.replace(front_end.low_pri_executor());
|
||||
FRONT_END.with(|f| *f.borrow_mut() = Some(Rc::clone(&front_end)));
|
||||
|
||||
Ok(front_end)
|
||||
@ -105,5 +118,6 @@ pub trait FrontEnd: Downcast {
|
||||
) -> Fallible<()>;
|
||||
|
||||
fn executor(&self) -> Box<dyn Executor>;
|
||||
fn low_pri_executor(&self) -> Box<dyn Executor>;
|
||||
}
|
||||
impl_downcast!(FrontEnd);
|
||||
|
@ -65,6 +65,10 @@ impl FrontEnd for MuxServerFrontEnd {
|
||||
})
|
||||
}
|
||||
|
||||
fn low_pri_executor(&self) -> Box<dyn Executor> {
|
||||
self.executor()
|
||||
}
|
||||
|
||||
fn run_forever(&self) -> Result<(), Error> {
|
||||
loop {
|
||||
match self.rx.recv() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::config::Config;
|
||||
use crate::frontend::executor;
|
||||
use crate::frontend::{executor, low_pri_executor};
|
||||
use crate::mux::tab::{Tab, TabId};
|
||||
use crate::mux::window::{Window, WindowId};
|
||||
use crate::ratelim::RateLimiter;
|
||||
@ -75,7 +75,7 @@ fn read_from_tab_pty(config: Arc<Config>, tab_id: TabId, mut reader: Box<dyn std
|
||||
let len = len as usize;
|
||||
let data = buf[pos..pos + len].to_vec();
|
||||
pos += len;
|
||||
Future::with_executor(executor(), move || {
|
||||
Future::with_executor(low_pri_executor(), move || {
|
||||
let mux = Mux::get().unwrap();
|
||||
if let Some(tab) = mux.get_tab(tab_id) {
|
||||
tab.advance_bytes(
|
||||
|
@ -67,6 +67,10 @@ impl Connection {
|
||||
pub fn executor() -> impl BasicExecutor {
|
||||
SpawnQueueExecutor {}
|
||||
}
|
||||
|
||||
pub fn low_pri_executor() -> impl BasicExecutor {
|
||||
LowPriSpawnQueueExecutor {}
|
||||
}
|
||||
}
|
||||
|
||||
impl ConnectionOps for Connection {
|
||||
|
@ -127,6 +127,10 @@ impl Connection {
|
||||
SpawnQueueExecutor {}
|
||||
}
|
||||
|
||||
pub fn low_pri_executor() -> impl BasicExecutor {
|
||||
LowPriSpawnQueueExecutor {}
|
||||
}
|
||||
|
||||
fn get_window(&self, handle: HWindow) -> Option<Rc<RefCell<WindowInner>>> {
|
||||
self.windows.borrow().get(&handle).map(Rc::clone)
|
||||
}
|
||||
|
@ -482,6 +482,10 @@ impl Connection {
|
||||
SpawnQueueExecutor {}
|
||||
}
|
||||
|
||||
pub fn low_pri_executor() -> impl BasicExecutor {
|
||||
LowPriSpawnQueueExecutor {}
|
||||
}
|
||||
|
||||
pub(crate) fn with_window_inner<F: FnMut(&mut WindowInner) + Send + 'static>(
|
||||
window: xcb::xproto::Window,
|
||||
mut f: F,
|
||||
|
@ -20,6 +20,7 @@ lazy_static::lazy_static! {
|
||||
|
||||
pub(crate) struct SpawnQueue {
|
||||
spawned_funcs: Mutex<VecDeque<SpawnFunc>>,
|
||||
spawned_funcs_low_pri: Mutex<VecDeque<SpawnFunc>>,
|
||||
|
||||
#[cfg(windows)]
|
||||
pub event_handle: EventHandle,
|
||||
@ -36,7 +37,7 @@ impl SpawnQueue {
|
||||
}
|
||||
|
||||
pub fn spawn(&self, f: SpawnFunc) {
|
||||
self.spawn_impl(f)
|
||||
self.spawn_impl(f, true)
|
||||
}
|
||||
|
||||
pub fn run(&self) -> bool {
|
||||
@ -47,7 +48,20 @@ impl SpawnQueue {
|
||||
// in order for the lock to be released before we call the
|
||||
// returned function
|
||||
fn pop_func(&self) -> Option<SpawnFunc> {
|
||||
self.spawned_funcs.lock().unwrap().pop_front()
|
||||
if let Some(func) = self.spawned_funcs.lock().unwrap().pop_front() {
|
||||
Some(func)
|
||||
} else {
|
||||
self.spawned_funcs_low_pri.lock().unwrap().pop_front()
|
||||
}
|
||||
}
|
||||
|
||||
fn queue_func(&self, f: SpawnFunc, high_pri: bool) {
|
||||
if high_pri {
|
||||
self.spawned_funcs.lock().unwrap()
|
||||
} else {
|
||||
self.spawned_funcs_low_pri.lock().unwrap()
|
||||
}
|
||||
.push_back(f);
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,8 +76,8 @@ impl SpawnQueue {
|
||||
})
|
||||
}
|
||||
|
||||
fn spawn_impl(&self, f: SpawnFunc) {
|
||||
self.spawned_funcs.lock().unwrap().push_back(f);
|
||||
fn spawn_impl(&self, f: SpawnFunc, high_pri: bool) {
|
||||
self.queue_func(f, high_pri);
|
||||
self.event_handle.set_event();
|
||||
}
|
||||
|
||||
@ -99,15 +113,16 @@ impl SpawnQueue {
|
||||
}
|
||||
Ok(Self {
|
||||
spawned_funcs: Mutex::new(VecDeque::new()),
|
||||
spawned_funcs_low_pri: Mutex::new(VecDeque::new()),
|
||||
write: Mutex::new(pipe.write),
|
||||
read: Mutex::new(pipe.read),
|
||||
})
|
||||
}
|
||||
|
||||
fn spawn_impl(&self, f: SpawnFunc) {
|
||||
fn spawn_impl(&self, f: SpawnFunc, high_pri: bool) {
|
||||
use std::io::Write;
|
||||
|
||||
self.spawned_funcs.lock().unwrap().push_back(f);
|
||||
self.queue_func(f, high_pri);
|
||||
self.write.lock().unwrap().write(b"x").ok();
|
||||
}
|
||||
|
||||
@ -193,8 +208,8 @@ impl SpawnQueue {
|
||||
}
|
||||
}
|
||||
|
||||
fn spawn_impl(&self, f: SpawnFunc) {
|
||||
self.spawned_funcs.lock().unwrap().push_back(f);
|
||||
fn spawn_impl(&self, f: SpawnFunc, high_pri: bool) {
|
||||
self.queue_func(f, high_pri);
|
||||
self.queue_wakeup();
|
||||
}
|
||||
|
||||
@ -214,3 +229,10 @@ impl BasicExecutor for SpawnQueueExecutor {
|
||||
SPAWN_QUEUE.spawn(f)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LowPriSpawnQueueExecutor;
|
||||
impl BasicExecutor for LowPriSpawnQueueExecutor {
|
||||
fn execute(&self, f: SpawnFunc) {
|
||||
SPAWN_QUEUE.spawn_impl(f, false)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user