Path: blob/main/crates/misc/component-async-tests/src/yield_host.rs
3068 views
use super::Ctx;1use futures::future;2use std::ops::DerefMut;3use std::sync::{Arc, Mutex};4use std::task::{Poll, Waker};5use wasmtime::component::{Accessor, Resource};67pub mod bindings {8wasmtime::component::bindgen!({9path: "wit",10world: "yield-host",11imports: { default: trappable },12with: {13"local:local/ready.thing": super::Thing,14},15});16}1718#[derive(Default)]19pub struct Thing {20wakers: Arc<Mutex<Option<Vec<Waker>>>>,21}2223impl bindings::local::local::continue_::Host for Ctx {24fn set_continue(&mut self, v: bool) -> wasmtime::Result<()> {25self.continue_ = v;26Ok(())27}2829fn get_continue(&mut self) -> wasmtime::Result<bool> {30Ok(self.continue_)31}32}3334impl bindings::local::local::ready::HostThing for Ctx {35fn new(&mut self) -> wasmtime::Result<Resource<Thing>> {36Ok(self.table.push(Thing::default())?)37}3839fn set_ready(&mut self, thing: Resource<Thing>, ready: bool) -> wasmtime::Result<()> {40let thing = self.table.get(&thing)?;41let mut wakers = thing.wakers.lock().unwrap();42if ready {43if let Some(wakers) = wakers.take() {44for waker in wakers {45waker.wake();46}47}48} else if wakers.is_none() {49*wakers = Some(Vec::new());50}51Ok(())52}5354fn drop(&mut self, thing: Resource<Thing>) -> wasmtime::Result<()> {55self.table.delete(thing)?;56Ok(())57}58}5960impl bindings::local::local::ready::HostThingWithStore for Ctx {61async fn when_ready<T>(62accessor: &Accessor<T, Self>,63thing: Resource<Thing>,64) -> wasmtime::Result<()> {65let wakers = accessor.with(|mut view| {66Ok::<_, wasmtime::Error>(view.get().table.get(&thing)?.wakers.clone())67})?;6869future::poll_fn(move |cx| {70let mut wakers = wakers.lock().unwrap();71if let Some(wakers) = wakers.deref_mut() {72wakers.push(cx.waker().clone());73Poll::Pending74} else {75Poll::Ready(())76}77})78.await;7980Ok(())81}82}8384impl bindings::local::local::ready::Host for Ctx {}858687