Skip to content

Commit

Permalink
Updated the documentation for VirtualTaskManager
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael-F-Bryan committed Aug 28, 2023
1 parent 95cedc5 commit 9702f5c
Showing 1 changed file with 53 additions and 13 deletions.
66 changes: 53 additions & 13 deletions lib/wasix/src/runtime/task_manager/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,21 @@ impl<'a, 'b> TaskWasm<'a, 'b> {
}
}

/// An implementation of task management
/// A task executor backed by a thread pool.
///
/// ## Thread Safety
///
/// Due to [#4158], it is possible to pass non-thread safe objects across
/// threads by capturing them in the task passed to
/// [`VirtualTaskManager::task_shared()`] or
/// [`VirtualTaskManager::task_dedicated()`].
///
/// If your task needs access to a [`wasmer::Module`], [`wasmer::Memory`], or
/// [`wasmer::Instance`], it should explicitly transfer the objects using
/// either [`VirtualTaskManager::task_wasm()`] when in syscall context or
/// [`VirtualTaskManager::spawn_with_module()`] for higher level code.
///
/// [#4158]: https://github.com/wasmerio/wasmer/issues/4158
#[allow(unused_variables)]
pub trait VirtualTaskManager: std::fmt::Debug + Send + Sync + 'static {
/// Build a new Webassembly memory.
Expand Down Expand Up @@ -130,34 +144,44 @@ pub trait VirtualTaskManager: std::fmt::Debug + Send + Sync + 'static {
}
}

/// Invokes whenever a WASM thread goes idle. In some runtimes (like singlethreaded
/// execution environments) they will need to do asynchronous work whenever the main
/// thread goes idle and this is the place to hook for that.
/// Pause the current thread of execution.
///
/// This is typically invoked whenever a WASM thread goes idle. Besides
/// acting as a platform-agnostic [`std::thread::sleep()`], this also gives
/// the runtime a chance to do asynchronous work like pumping an event
/// loop.
fn sleep_now(
&self,
time: Duration,
) -> Pin<Box<dyn Future<Output = ()> + Send + Sync + 'static>>;

/// Starts an asynchronous task that will run on a shared worker pool
/// This task must not block the execution or it could cause a deadlock
/// Run an asynchronous operation on the thread pool.
///
/// This task must not block execution or it could cause deadlocks.
///
/// See the "Thread Safety" documentation on [`VirtualTaskManager`] for
/// limitations on what a `task` can and can't contain.
fn task_shared(
&self,
task: Box<dyn FnOnce() -> BoxFuture<'static, ()> + Send + 'static>,
) -> Result<(), WasiThreadError>;

/// Starts an WebAssembly task will will run on a dedicated thread
/// pulled from the worker pool that has a stateful thread local variable
/// Run a blocking WebAssembly operation on the thread pool.
///
/// This is primarily used inside the context of a syscall and allows
/// the transfer of things like [`wasmer::Module`] across threads.
fn task_wasm(&self, task: TaskWasm) -> Result<(), WasiThreadError>;

/// Starts an asynchronous task will will run on a dedicated thread
/// pulled from the worker pool. It is ok for this task to block execution
/// and any async futures within its scope
/// Run a blocking operation on the thread pool.
///
/// It is okay for this task to block execution and any async futures within
/// its scope.
fn task_dedicated(
&self,
task: Box<dyn FnOnce() + Send + 'static>,
) -> Result<(), WasiThreadError>;

/// Returns the amount of parallelism that is possible on this platform
/// Returns the amount of parallelism that is possible on this platform.
fn thread_parallelism(&self) -> Result<usize, WasiThreadError>;

/// Schedule a blocking task to run on the threadpool, explicitly
Expand All @@ -166,14 +190,22 @@ pub trait VirtualTaskManager: std::fmt::Debug + Send + Sync + 'static {
/// This should be preferred over [`VirtualTaskManager::task_dedicated()`]
/// where possible because [`wasmer::Module`] is actually `!Send` in the
/// browser and can only be transferred to background threads via
/// an explicit `postMessage()`. See [#4158] for more.
/// an explicit `postMessage()`. See [#4158] for more details.
///
/// This is very similar to [`VirtualTaskManager::task_wasm()`], but
/// intended for use outside of a syscall context. For example, when you are
/// running in the browser and want to run a WebAssembly module in the
/// background.
///
/// [#4158]: https://github.com/wasmerio/wasmer/issues/4158
fn spawn_with_module(
&self,
module: Module,
task: Box<dyn FnOnce(Module) + Send + 'static>,
) -> Result<(), WasiThreadError> {
// Note: Ideally, this function and task_wasm() would be superseded by
// a more general mechanism for transferring non-thread safe values
// to the thread pool.
self.task_dedicated(Box::new(move || task(module)))
}
}
Expand Down Expand Up @@ -219,6 +251,14 @@ where
fn thread_parallelism(&self) -> Result<usize, WasiThreadError> {
(**self).thread_parallelism()
}

fn spawn_with_module(
&self,
module: Module,
task: Box<dyn FnOnce(Module) + Send + 'static>,
) -> Result<(), WasiThreadError> {
(**self).spawn_with_module(module, task)
}
}

impl dyn VirtualTaskManager {
Expand Down

0 comments on commit 9702f5c

Please sign in to comment.