Skip to content
Open
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
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ serde_json = { workspace = true, optional = true }
wasip2.workspace = true

[target.'cfg(all(target_os = "wasi", target_env = "p3"))'.dependencies]
wasip3.workspace = true
wasip3 = { workspace = true, features = ["async-spawn"] }

[dev-dependencies]
anyhow.workspace = true
Expand Down
15 changes: 2 additions & 13 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,21 +67,10 @@ pub mod iter;
pub mod net;
#[cfg(target_os = "wasi")]
pub mod rand;
#[cfg(all(target_os = "wasi", target_env = "p2"))]
pub mod runtime;
#[cfg(all(target_os = "wasi", target_env = "p3"))]
pub mod runtime {
pub fn block_on<F, T>(fut: F) -> F::Output
where
F: Future<Output = T>,
T: 'static,
{
wasip3::wit_bindgen::block_on(fut)
}
}
#[cfg(all(target_os = "wasi", target_env = "p2"))]
#[cfg(target_os = "wasi")]
pub mod task;
#[cfg(all(target_os = "wasi", target_env = "p2"))]
#[cfg(target_os = "wasi")]
pub mod time;

#[cfg(all(target_os = "wasi", target_env = "p2"))]
Expand Down
43 changes: 39 additions & 4 deletions src/runtime/mod.rs
Original file line number Diff line number Diff line change
@@ -1,36 +1,71 @@
//! Async event loop support.
//!
//! The way to use this is to call [`block_on()`]. Inside the future, [`Reactor::current`]
//! will give an instance of the [`Reactor`] running the event loop, which can be
//! to [`AsyncPollable::wait_for`] instances of
//! On WASI 0.2 the way to use this is to call [`block_on()`]. Inside the
//! future, [`Reactor::current`] will give an instance of the [`Reactor`]
//! running the event loop, which can be used to [`AsyncPollable::wait_for`]
//! instances of
//! [`wasip2::Pollable`](https://docs.rs/wasi/latest/wasi/io/poll/struct.Pollable.html).
//! This will automatically wait for the futures to resolve, and call the
//! necessary wakers to work.
//!
//! On WASI 0.3 [`block_on`] can be used to drive a future, but an async
//! function can also be directly exported and will be driven by the host.

#![deny(missing_debug_implementations, nonstandard_style)]
#![warn(missing_docs, unreachable_pub)]

pub use ::async_task::Task;

#[cfg(target_env = "p2")]
mod block_on;
#[cfg(target_env = "p2")]
mod reactor;

pub use ::async_task::Task;
#[cfg(target_env = "p2")]
pub use block_on::block_on;
#[cfg(target_env = "p2")]
pub use reactor::{AsyncPollable, Reactor, WaitFor};
#[cfg(target_env = "p2")]
use std::cell::RefCell;

// There are no threads in WASI 0.2, so this is just a safe way to thread a single reactor to all
// use sites in the background.
#[cfg(target_env = "p2")]
std::thread_local! {
pub(crate) static REACTOR: RefCell<Option<Reactor>> = const { RefCell::new(None) };
}

/// Spawn a `Future` as a `Task` on the current `Reactor`.
///
/// Panics if called from outside `block_on`.
#[cfg(target_env = "p2")]
pub fn spawn<F, T>(fut: F) -> Task<T>
where
F: std::future::Future<Output = T> + 'static,
T: 'static,
{
Reactor::current().spawn(fut)
}

#[cfg(target_env = "p3")]
pub use ::async_task::Runnable;
#[cfg(target_env = "p3")]
pub use wasip3::wit_bindgen::block_on;

/// Spawn a `Future` as a `Task` on the WASI 0.3 async runtime.
#[cfg(target_env = "p3")]
pub fn spawn<F, T>(fut: F) -> Task<T>
where
F: std::future::Future<Output = T> + 'static,
T: 'static,
{
let (runnable, task) = async_task::spawn_local(fut, |runnable: Runnable| {
// Scheduling the task is accomplished by spawning a future which
// executes the `run` method.
wasip3::spawn_local(async move {
let _ = runnable.run();
});
});
runnable.schedule();
task
}
3 changes: 3 additions & 0 deletions src/time/duration.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use super::{Instant, Wait};
use std::future::IntoFuture;
use std::ops::{Add, AddAssign, Sub, SubAssign};
#[cfg(target_env = "p2")]
use wasip2::clocks::monotonic_clock;
#[cfg(target_env = "p3")]
use wasip3::clocks::monotonic_clock;

/// A Duration type to represent a span of time, typically used for system
/// timeouts.
Expand Down
9 changes: 6 additions & 3 deletions src/time/instant.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use super::{Duration, Wait};
use std::future::IntoFuture;
use std::ops::{Add, AddAssign, Sub, SubAssign};
use wasip2::clocks::monotonic_clock;
#[cfg(target_env = "p2")]
use wasip2::clocks::monotonic_clock::{self, Instant as WasiInstant};
#[cfg(target_env = "p3")]
use wasip3::clocks::monotonic_clock::{self, Mark as WasiInstant};

/// A measurement of a monotonically nondecreasing clock. Opaque and useful only
/// with Duration.
Expand All @@ -10,7 +13,7 @@ use wasip2::clocks::monotonic_clock;
/// without coherence issues, just like if we were implementing this in the
/// stdlib.
#[derive(Debug, PartialEq, PartialOrd, Ord, Eq, Hash, Clone, Copy)]
pub struct Instant(pub(crate) monotonic_clock::Instant);
pub struct Instant(pub(crate) WasiInstant);

impl Instant {
/// Returns an instant corresponding to "now".
Expand All @@ -24,7 +27,7 @@ impl Instant {
/// ```
#[must_use]
pub fn now() -> Self {
Instant(wasip2::clocks::monotonic_clock::now())
Instant(monotonic_clock::now())
}

/// Returns the amount of time elapsed from another instant to this one, or zero duration if
Expand Down
Loading
Loading