Make it possible to cleanly close plugins

This commit is contained in:
Brooks J Rady 2021-01-07 13:26:27 +00:00
parent 2b91514a8f
commit adfe7fd513
3 changed files with 35 additions and 16 deletions

View file

@ -183,6 +183,7 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: Opt) {
let mut pty_bus = PtyBus::new( let mut pty_bus = PtyBus::new(
receive_pty_instructions, receive_pty_instructions,
send_screen_instructions.clone(), send_screen_instructions.clone(),
send_plugin_instructions.clone(),
os_input.clone(), os_input.clone(),
opts.debug, opts.debug,
); );
@ -438,21 +439,23 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: Opt) {
.read(true) .read(true)
.write(true) .write(true)
.create(true) .create(true)
}).unwrap() })
.unwrap()
.stdin(Box::new(input)) .stdin(Box::new(input))
.stdout(Box::new(output)) .stdout(Box::new(output))
.finalize().unwrap(); .finalize()
.unwrap();
let wasi = wasi_env.import_object(&module).unwrap(); let wasi = wasi_env.import_object(&module).unwrap();
let mosaic = mosaic_imports(&store, &wasi_env); let mosaic = mosaic_imports(&store, &wasi_env);
let instance = Instance::new(&module, &mosaic.chain_back(wasi)).unwrap(); let instance =
Instance::new(&module, &mosaic.chain_back(wasi)).unwrap();
let start = instance.exports.get_function("_start").unwrap(); let start = instance.exports.get_function("_start").unwrap();
// This eventually calls the `.init()` method // This eventually calls the `.init()` method
start.call(&[]).unwrap(); start.call(&[]).unwrap();
debug_log_to_file(format!("Loaded {}({}) from {}", instance.module().name().unwrap(), plugin_id, path.display())).unwrap();
plugin_map.insert(plugin_id, (instance, wasi_env)); plugin_map.insert(plugin_id, (instance, wasi_env));
pid_tx.send(plugin_id).unwrap(); pid_tx.send(plugin_id).unwrap();
plugin_id += 1; plugin_id += 1;
@ -462,30 +465,37 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: Opt) {
let draw = instance.exports.get_function("draw").unwrap(); let draw = instance.exports.get_function("draw").unwrap();
draw.call(&[Value::I32(rows as i32), Value::I32(cols as i32)]).unwrap(); draw.call(&[Value::I32(rows as i32), Value::I32(cols as i32)])
.unwrap();
buf_tx.send(wasi_stdout(&wasi_env)).unwrap(); buf_tx.send(wasi_stdout(&wasi_env)).unwrap();
} }
PluginInstruction::Input(pid, input_bytes) => { PluginInstruction::Input(pid, input_bytes) => {
let (instance, wasi_env) = plugin_map.get(&pid).unwrap(); let (instance, wasi_env) = plugin_map.get(&pid).unwrap();
let handle_key = instance.exports.get_function("handle_key").unwrap(); let handle_key =
instance.exports.get_function("handle_key").unwrap();
for key in input_bytes.keys() { for key in input_bytes.keys() {
if let Ok(key) = key { if let Ok(key) = key {
wasi_write_string(wasi_env, &serde_json::to_string(&key).unwrap()); wasi_write_string(
wasi_env,
&serde_json::to_string(&key).unwrap(),
);
handle_key.call(&[]).unwrap(); handle_key.call(&[]).unwrap();
} }
} }
send_screen_instructions.send(ScreenInstruction::Render).unwrap(); send_screen_instructions
.send(ScreenInstruction::Render)
.unwrap();
} }
PluginInstruction::Unload(pid) => drop(plugin_map.remove(&pid)),
PluginInstruction::Quit => break, PluginInstruction::Quit => break,
i => panic!("Yo, dawg, nice job calling the wasm thread!\n {:?} is defo not implemented yet...", i),
} }
} }
} }
} })
).unwrap(), .unwrap(),
); );
// TODO: currently we don't push this into active_threads // TODO: currently we don't push this into active_threads

View file

@ -9,13 +9,13 @@ use ::std::time::{Duration, Instant};
use ::vte; use ::vte;
use std::path::PathBuf; use std::path::PathBuf;
use crate::layout::Layout;
use crate::os_input_output::OsApi; use crate::os_input_output::OsApi;
use crate::utils::logging::debug_to_file; use crate::utils::logging::debug_to_file;
use crate::{ use crate::{
errors::{ContextType, ErrorContext}, errors::{ContextType, ErrorContext},
panes::PaneId, panes::PaneId,
}; };
use crate::{layout::Layout, wasm_vm::PluginInstruction};
use crate::{ScreenInstruction, SenderWithContext, OPENCALLS}; use crate::{ScreenInstruction, SenderWithContext, OPENCALLS};
pub struct ReadFromPid { pub struct ReadFromPid {
@ -158,6 +158,7 @@ pub enum PtyInstruction {
pub struct PtyBus { pub struct PtyBus {
pub send_screen_instructions: SenderWithContext<ScreenInstruction>, pub send_screen_instructions: SenderWithContext<ScreenInstruction>,
pub send_plugin_instructions: SenderWithContext<PluginInstruction>,
pub receive_pty_instructions: Receiver<(PtyInstruction, ErrorContext)>, pub receive_pty_instructions: Receiver<(PtyInstruction, ErrorContext)>,
pub id_to_child_pid: HashMap<RawFd, RawFd>, pub id_to_child_pid: HashMap<RawFd, RawFd>,
os_input: Box<dyn OsApi>, os_input: Box<dyn OsApi>,
@ -244,11 +245,13 @@ impl PtyBus {
pub fn new( pub fn new(
receive_pty_instructions: Receiver<(PtyInstruction, ErrorContext)>, receive_pty_instructions: Receiver<(PtyInstruction, ErrorContext)>,
send_screen_instructions: SenderWithContext<ScreenInstruction>, send_screen_instructions: SenderWithContext<ScreenInstruction>,
send_plugin_instructions: SenderWithContext<PluginInstruction>,
os_input: Box<dyn OsApi>, os_input: Box<dyn OsApi>,
debug_to_file: bool, debug_to_file: bool,
) -> Self { ) -> Self {
PtyBus { PtyBus {
send_screen_instructions, send_screen_instructions,
send_plugin_instructions,
receive_pty_instructions, receive_pty_instructions,
os_input, os_input,
id_to_child_pid: HashMap::new(), id_to_child_pid: HashMap::new(),
@ -291,10 +294,16 @@ impl PtyBus {
} }
} }
pub fn close_pane(&mut self, id: PaneId) { pub fn close_pane(&mut self, id: PaneId) {
if let PaneId::Terminal(id) = id { match id {
PaneId::Terminal(id) => {
let child_pid = self.id_to_child_pid.get(&id).unwrap(); let child_pid = self.id_to_child_pid.get(&id).unwrap();
self.os_input.kill(*child_pid).unwrap(); self.os_input.kill(*child_pid).unwrap();
} }
PaneId::Plugin(pid) => self
.send_plugin_instructions
.send(PluginInstruction::Unload(pid))
.unwrap(),
}
} }
pub fn close_tab(&mut self, ids: Vec<PaneId>) { pub fn close_tab(&mut self, ids: Vec<PaneId>) {
ids.iter().for_each(|&id| self.close_pane(id)); ids.iter().for_each(|&id| self.close_pane(id));

View file

@ -1689,7 +1689,7 @@ impl Tab {
} }
} }
pub fn close_pane_without_rerender(&mut self, id: PaneId) { pub fn close_pane_without_rerender(&mut self, id: PaneId) {
if let Some(terminal_to_close) = &self.panes.get(&id) { if let Some(terminal_to_close) = self.panes.get(&id) {
let terminal_to_close_width = terminal_to_close.columns(); let terminal_to_close_width = terminal_to_close.columns();
let terminal_to_close_height = terminal_to_close.rows(); let terminal_to_close_height = terminal_to_close.rows();
if let Some(terminals) = self.panes_to_the_left_between_aligning_borders(id) { if let Some(terminals) = self.panes_to_the_left_between_aligning_borders(id) {