diff options
| author | Aram Drevekenin <aram@poor.dev> | 2025-10-21 14:36:30 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-10-21 14:36:30 +0200 |
| commit | 889bd06f447f9d50ee46b8efc7d9970d3693cb96 (patch) | |
| tree | 171fa657faccf4b4ce7124847977626826a2a750 /zellij-server/src/plugins/plugin_map.rs | |
| parent | Give plugins the ability to read pane contents (#4465) (diff) | |
| download | sl0ppij-889bd06f447f9d50ee46b8efc7d9970d3693cb96.tar.gz sl0ppij-889bd06f447f9d50ee46b8efc7d9970d3693cb96.tar.xz sl0ppij-889bd06f447f9d50ee46b8efc7d9970d3693cb96.zip | |
Migrate from wasmtime to wasmi (#4449)
* initial implementation
* fix stdio and host folder mounting
* some memory usage optimizations
* fix plugin tests
* remove unused plugin cache
* fix docker-compose for e2e tests when running locally
* rustfmt
* initial pinned executor implementation
* EXPERIMENT: add jemalloc
* initial dynamic pinned threadpool
* cleanups and experiments
* keep state on execution threads
* reintroduce memory cache
* add wasmi engine to executor threads
* load plugins for new clients on the relevant executor thread
* only show loading indication of loading for more than 0.4 secs
* fix anonymous plugin loading without client id
* refactor lots of stuff
* update snapshots
* tests for pinned executor
* remove jemalloc
* fix stderr from plugins
* cleanups
* rustfmt
* cleanups
* fix endless loading for additinal attachments
* more cleanups
* remove singlepass feature
* fix displaying plugin permission message
* render optimizations
* always render for tests
* rustfmt
* optimize release build for wasmi
* fixes for multiple client plugin loading
* fix frame rendering for multiple clients
* rustfmt
* fix loading background plugins and e2e event ordering change
* rustfmt
* account for races in the pin_floating_panes e2e test
* docs(changelog): add PR
Diffstat (limited to 'zellij-server/src/plugins/plugin_map.rs')
| -rw-r--r-- | zellij-server/src/plugins/plugin_map.rs | 88 |
1 files changed, 18 insertions, 70 deletions
diff --git a/zellij-server/src/plugins/plugin_map.rs b/zellij-server/src/plugins/plugin_map.rs index a92c291a..7520114f 100644 --- a/zellij-server/src/plugins/plugin_map.rs +++ b/zellij-server/src/plugins/plugin_map.rs @@ -1,18 +1,13 @@ use crate::plugins::plugin_worker::MessageToWorker; use crate::plugins::PluginId; -use bytes::Bytes; use std::io::Write; use std::{ collections::{BTreeMap, HashMap, HashSet, VecDeque}, path::PathBuf, sync::{Arc, Mutex}, }; -use wasmtime::{Instance, Store}; -use wasmtime_wasi::preview1::WasiP1Ctx; -use wasmtime_wasi::{ - HostInputStream, HostOutputStream, StdinStream, StdoutStream, StreamError, StreamResult, - Subscribe, -}; +use wasmi::{Instance, Store, StoreLimits}; +use wasmi_wasi::WasiCtx; use crate::{thread_bus::ThreadSenders, ClientId}; @@ -70,17 +65,6 @@ impl PluginMap { } removed } - pub fn remove_single_plugin( - &mut self, - plugin_id: PluginId, - client_id: ClientId, - ) -> Option<( - Arc<Mutex<RunningPlugin>>, - Arc<Mutex<Subscriptions>>, - HashMap<String, Sender<MessageToWorker>>, - )> { - self.plugin_assets.remove(&(plugin_id, client_id)) - } pub fn plugin_ids(&self) -> Vec<PluginId> { let mut unique_plugins: HashSet<PluginId> = self .plugin_assets @@ -293,7 +277,7 @@ pub struct PluginEnv { pub plugin: PluginConfig, pub permissions: Arc<Mutex<Option<HashSet<PermissionType>>>>, pub senders: ThreadSenders, - pub wasi_ctx: WasiP1Ctx, + pub wasi_ctx: WasiCtx, pub tab_index: Option<usize>, pub client_id: ClientId, #[allow(dead_code)] @@ -314,34 +298,23 @@ pub struct PluginEnv { pub stdout_pipe: Arc<Mutex<VecDeque<u8>>>, pub keybinds: Keybinds, pub intercepting_key_presses: bool, + pub store_limits: StoreLimits, } #[derive(Clone)] pub struct VecDequeInputStream(pub Arc<Mutex<VecDeque<u8>>>); -impl StdinStream for VecDequeInputStream { - fn stream(&self) -> Box<dyn wasmtime_wasi::HostInputStream> { - Box::new(self.clone()) - } - - fn isatty(&self) -> bool { - false - } -} - -impl HostInputStream for VecDequeInputStream { - fn read(&mut self, size: usize) -> StreamResult<Bytes> { +impl std::io::Read for VecDequeInputStream { + fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> { let mut inner = self.0.lock().unwrap(); - let len = std::cmp::min(size, inner.len()); - Ok(Bytes::from_iter(inner.drain(0..len))) + let len = std::cmp::min(buf.len(), inner.len()); + for (i, byte) in inner.drain(0..len).enumerate() { + buf[i] = byte; + } + Ok(len) } } -#[async_trait::async_trait] -impl Subscribe for VecDequeInputStream { - async fn ready(&mut self) {} -} - pub struct WriteOutputStream<T>(pub Arc<Mutex<T>>); impl<T> Clone for WriteOutputStream<T> { @@ -350,43 +323,18 @@ impl<T> Clone for WriteOutputStream<T> { } } -impl<T: Write + Send + 'static> StdoutStream for WriteOutputStream<T> { - fn stream(&self) -> Box<dyn HostOutputStream> { - Box::new((*self).clone()) - } - - fn isatty(&self) -> bool { - false - } -} - -impl<T: Write + Send + 'static> HostOutputStream for WriteOutputStream<T> { - fn write(&mut self, bytes: Bytes) -> StreamResult<()> { - self.0 - .lock() - .unwrap() - .write_all(&*bytes) - .map_err(|e| StreamError::LastOperationFailed(e.into())) - } - - fn flush(&mut self) -> StreamResult<()> { - self.0 - .lock() - .unwrap() - .flush() - .map_err(|e| StreamError::LastOperationFailed(e.into())) +impl<T: Write + Send + 'static> std::io::Write for WriteOutputStream<T> { + fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> { + let mut inner = self.0.lock().unwrap(); + inner.write(buf) } - fn check_write(&mut self) -> StreamResult<usize> { - Ok(usize::MAX) + fn flush(&mut self) -> std::io::Result<()> { + let mut inner = self.0.lock().unwrap(); + inner.flush() } } -#[async_trait::async_trait] -impl<T: Send + 'static> Subscribe for WriteOutputStream<T> { - async fn ready(&mut self) {} -} - impl PluginEnv { // Get the name (path) of the containing plugin pub fn name(&self) -> String { |
