Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WasiCtx paramaterized by WasiExecutor #9984

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 21 additions & 54 deletions crates/wasi/src/ctx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ use crate::{
},
filesystem::{Dir, OpenMode},
network::{SocketAddrCheck, SocketAddrUse},
pipe, random, stdio,
pipe, random,
runtime::WasiExecutor,
stdio,
stdio::{StdinStream, StdoutStream},
DirPerms, FilePerms,
};
Expand Down Expand Up @@ -52,7 +54,6 @@ pub struct WasiCtxBuilder {
wall_clock: Box<dyn HostWallClock + Send>,
monotonic_clock: Box<dyn HostMonotonicClock + Send>,
allowed_network_uses: AllowedNetworkUses,
allow_blocking_current_thread: bool,
built: bool,
}

Expand Down Expand Up @@ -101,7 +102,6 @@ impl WasiCtxBuilder {
wall_clock: wall_clock(),
monotonic_clock: monotonic_clock(),
allowed_network_uses: AllowedNetworkUses::default(),
allow_blocking_current_thread: false,
built: false,
}
}
Expand Down Expand Up @@ -175,37 +175,6 @@ impl WasiCtxBuilder {
self.inherit_stdin().inherit_stdout().inherit_stderr()
}

/// Configures whether or not blocking operations made through this
/// `WasiCtx` are allowed to block the current thread.
///
/// WASI is currently implemented on top of the Rust
/// [Tokio](https://tokio.rs/) library. While most WASI APIs are
/// non-blocking some are instead blocking from the perspective of
/// WebAssembly. For example opening a file is a blocking operation with
/// respect to WebAssembly but it's implemented as an asynchronous operation
/// on the host. This is currently done with Tokio's
/// [`spawn_blocking`](https://docs.rs/tokio/latest/tokio/task/fn.spawn_blocking.html).
///
/// When WebAssembly is used in a synchronous context, for example when
/// [`Config::async_support`] is disabled, then this asynchronous operation
/// is quickly turned back into a synchronous operation with a `block_on` in
/// Rust. This switching back-and-forth between a blocking a non-blocking
/// context can have overhead, and this option exists to help alleviate this
/// overhead.
///
/// This option indicates that for WASI functions that are blocking from the
/// perspective of WebAssembly it's ok to block the native thread as well.
/// This means that this back-and-forth between async and sync won't happen
/// and instead blocking operations are performed on-thread (such as opening
/// a file). This can improve the performance of WASI operations when async
/// support is disabled.
///
/// [`Config::async_support`]: https://docs.rs/wasmtime/latest/wasmtime/struct.Config.html#method.async_support
pub fn allow_blocking_current_thread(&mut self, enable: bool) -> &mut Self {
self.allow_blocking_current_thread = enable;
self
}

/// Appends multiple environment variables at once for this builder.
///
/// All environment variables are appended to the list of environment
Expand Down Expand Up @@ -340,13 +309,7 @@ impl WasiCtxBuilder {
open_mode |= OpenMode::WRITE;
}
self.preopens.push((
Dir::new(
dir,
dir_perms,
file_perms,
open_mode,
self.allow_blocking_current_thread,
),
Dir::new(dir, dir_perms, file_perms, open_mode),
guest_path.as_ref().to_owned(),
));
Ok(self)
Expand Down Expand Up @@ -463,7 +426,7 @@ impl WasiCtxBuilder {
/// Panics if this method is called twice. Each [`WasiCtxBuilder`] can be
/// used to create only a single [`WasiCtx`]. Repeated usage of this method
/// is not allowed and should use a second builder instead.
pub fn build(&mut self) -> WasiCtx {
pub fn build<E>(&mut self) -> WasiCtx<E> {
assert!(!self.built);

let Self {
Expand All @@ -480,7 +443,6 @@ impl WasiCtxBuilder {
wall_clock,
monotonic_clock,
allowed_network_uses,
allow_blocking_current_thread,
built: _,
} = mem::replace(self, Self::new());
self.built = true;
Expand All @@ -499,7 +461,7 @@ impl WasiCtxBuilder {
wall_clock,
monotonic_clock,
allowed_network_uses,
allow_blocking_current_thread,
_executor: std::marker::PhantomData,
}
}

Expand All @@ -519,7 +481,7 @@ impl WasiCtxBuilder {
/// usage of this method is not allowed and should use a second builder
/// instead.
#[cfg(feature = "preview1")]
pub fn build_p1(&mut self) -> crate::preview1::WasiP1Ctx {
pub fn build_p1<E>(&mut self) -> crate::preview1::WasiP1Ctx<E> {
let wasi = self.build();
crate::preview1::WasiP1Ctx::new(wasi)
}
Expand All @@ -545,15 +507,16 @@ impl WasiCtxBuilder {
/// # Example
///
/// ```
/// use wasmtime_wasi::{WasiCtx, ResourceTable, WasiView, WasiCtxBuilder};
/// use wasmtime_wasi::{WasiCtx, ResourceTable, WasiView, Tokio, WasiCtxBuilder};
///
/// struct MyState {
/// ctx: WasiCtx,
/// table: ResourceTable,
/// }
///
/// impl WasiView for MyState {
/// fn ctx(&mut self) -> &mut WasiCtx { &mut self.ctx }
/// type Executor = Tokio;
/// fn ctx(&mut self) -> &mut WasiCtx<Tokio> { &mut self.ctx }
/// fn table(&mut self) -> &mut ResourceTable { &mut self.table }
/// }
///
Expand All @@ -572,6 +535,7 @@ impl WasiCtxBuilder {
/// }
/// ```
pub trait WasiView: Send {
type Executor: WasiExecutor;
/// Yields mutable access to the internal resource management that this
/// context contains.
///
Expand All @@ -582,23 +546,25 @@ pub trait WasiView: Send {
/// Yields mutable access to the configuration used for this context.
///
/// The returned type is created through [`WasiCtxBuilder`].
fn ctx(&mut self) -> &mut WasiCtx;
fn ctx(&mut self) -> &mut WasiCtx<Self::Executor>;
}

impl<T: ?Sized + WasiView> WasiView for &mut T {
type Executor = T::Executor;
fn table(&mut self) -> &mut ResourceTable {
T::table(self)
}
fn ctx(&mut self) -> &mut WasiCtx {
fn ctx(&mut self) -> &mut WasiCtx<Self::Executor> {
T::ctx(self)
}
}

impl<T: ?Sized + WasiView> WasiView for Box<T> {
type Executor = T::Executor;
fn table(&mut self) -> &mut ResourceTable {
T::table(self)
}
fn ctx(&mut self) -> &mut WasiCtx {
fn ctx(&mut self) -> &mut WasiCtx<Self::Executor> {
T::ctx(self)
}
}
Expand All @@ -619,10 +585,11 @@ impl<T: ?Sized + WasiView> WasiView for Box<T> {
pub struct WasiImpl<T>(pub T);

impl<T: WasiView> WasiView for WasiImpl<T> {
type Executor = T::Executor;
fn table(&mut self) -> &mut ResourceTable {
T::table(&mut self.0)
}
fn ctx(&mut self) -> &mut WasiCtx {
fn ctx(&mut self) -> &mut WasiCtx<Self::Executor> {
T::ctx(&mut self.0)
}
}
Expand All @@ -639,7 +606,7 @@ impl<T: WasiView> WasiView for WasiImpl<T> {
/// bindgen-generated traits.
///
/// [`Store`]: wasmtime::Store
pub struct WasiCtx {
pub struct WasiCtx<E> {
pub(crate) random: Box<dyn RngCore + Send>,
pub(crate) insecure_random: Box<dyn RngCore + Send>,
pub(crate) insecure_random_seed: u128,
Expand All @@ -653,10 +620,10 @@ pub struct WasiCtx {
pub(crate) stderr: Box<dyn StdoutStream>,
pub(crate) socket_addr_check: SocketAddrCheck,
pub(crate) allowed_network_uses: AllowedNetworkUses,
pub(crate) allow_blocking_current_thread: bool,
pub(crate) _executor: std::marker::PhantomData<E>,
}

impl WasiCtx {
impl<E> WasiCtx<E> {
/// Convenience function for calling [`WasiCtxBuilder::new`].
pub fn builder() -> WasiCtxBuilder {
WasiCtxBuilder::new()
Expand Down
Loading
Loading