From adfe7fd51353ce9c5aa89a0f8c53212e9bbae278 Mon Sep 17 00:00:00 2001 From: Brooks J Rady Date: Thu, 7 Jan 2021 13:26:27 +0000 Subject: [PATCH] Make it possible to cleanly close plugins --- src/main.rs | 32 +++++++++++++++++++++----------- src/pty_bus.rs | 17 +++++++++++++---- src/tab.rs | 2 +- 3 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/main.rs b/src/main.rs index 918305c7..8593cb53 100644 --- a/src/main.rs +++ b/src/main.rs @@ -183,6 +183,7 @@ pub fn start(mut os_input: Box, opts: Opt) { let mut pty_bus = PtyBus::new( receive_pty_instructions, send_screen_instructions.clone(), + send_plugin_instructions.clone(), os_input.clone(), opts.debug, ); @@ -438,21 +439,23 @@ pub fn start(mut os_input: Box, opts: Opt) { .read(true) .write(true) .create(true) - }).unwrap() + }) + .unwrap() .stdin(Box::new(input)) .stdout(Box::new(output)) - .finalize().unwrap(); + .finalize() + .unwrap(); let wasi = wasi_env.import_object(&module).unwrap(); 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(); // This eventually calls the `.init()` method 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)); pid_tx.send(plugin_id).unwrap(); plugin_id += 1; @@ -462,30 +465,37 @@ pub fn start(mut os_input: Box, opts: Opt) { 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(); } PluginInstruction::Input(pid, input_bytes) => { 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() { 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(); } } - 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, - 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 diff --git a/src/pty_bus.rs b/src/pty_bus.rs index fdc8b889..e635b176 100644 --- a/src/pty_bus.rs +++ b/src/pty_bus.rs @@ -9,13 +9,13 @@ use ::std::time::{Duration, Instant}; use ::vte; use std::path::PathBuf; -use crate::layout::Layout; use crate::os_input_output::OsApi; use crate::utils::logging::debug_to_file; use crate::{ errors::{ContextType, ErrorContext}, panes::PaneId, }; +use crate::{layout::Layout, wasm_vm::PluginInstruction}; use crate::{ScreenInstruction, SenderWithContext, OPENCALLS}; pub struct ReadFromPid { @@ -158,6 +158,7 @@ pub enum PtyInstruction { pub struct PtyBus { pub send_screen_instructions: SenderWithContext, + pub send_plugin_instructions: SenderWithContext, pub receive_pty_instructions: Receiver<(PtyInstruction, ErrorContext)>, pub id_to_child_pid: HashMap, os_input: Box, @@ -244,11 +245,13 @@ impl PtyBus { pub fn new( receive_pty_instructions: Receiver<(PtyInstruction, ErrorContext)>, send_screen_instructions: SenderWithContext, + send_plugin_instructions: SenderWithContext, os_input: Box, debug_to_file: bool, ) -> Self { PtyBus { send_screen_instructions, + send_plugin_instructions, receive_pty_instructions, os_input, id_to_child_pid: HashMap::new(), @@ -291,9 +294,15 @@ impl PtyBus { } } pub fn close_pane(&mut self, id: PaneId) { - if let PaneId::Terminal(id) = id { - let child_pid = self.id_to_child_pid.get(&id).unwrap(); - self.os_input.kill(*child_pid).unwrap(); + match id { + PaneId::Terminal(id) => { + let child_pid = self.id_to_child_pid.get(&id).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) { diff --git a/src/tab.rs b/src/tab.rs index 5eafb9f8..ba98bbbd 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -1689,7 +1689,7 @@ impl Tab { } } 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_height = terminal_to_close.rows(); if let Some(terminals) = self.panes_to_the_left_between_aligning_borders(id) {