1*112112d4SAlex Crichton use super::Ctx; 2*112112d4SAlex Crichton use futures::future; 3*112112d4SAlex Crichton use std::ops::DerefMut; 4*112112d4SAlex Crichton use std::sync::{Arc, Mutex}; 5*112112d4SAlex Crichton use std::task::{Poll, Waker}; 6*112112d4SAlex Crichton use wasmtime::component::{Accessor, Resource}; 7*112112d4SAlex Crichton 8*112112d4SAlex Crichton pub mod bindings { 9*112112d4SAlex Crichton wasmtime::component::bindgen!({ 10*112112d4SAlex Crichton path: "wit", 11*112112d4SAlex Crichton world: "yield-runner", 12*112112d4SAlex Crichton imports: { default: trappable }, 13*112112d4SAlex Crichton with: { 14*112112d4SAlex Crichton "local:local/ready.thing": super::Thing, 15*112112d4SAlex Crichton }, 16*112112d4SAlex Crichton }); 17*112112d4SAlex Crichton } 18*112112d4SAlex Crichton 19*112112d4SAlex Crichton #[derive(Default)] 20*112112d4SAlex Crichton pub struct Thing { 21*112112d4SAlex Crichton wakers: Arc<Mutex<Option<Vec<Waker>>>>, 22*112112d4SAlex Crichton } 23*112112d4SAlex Crichton 24*112112d4SAlex Crichton impl bindings::local::local::continue_::Host for Ctx { set_continue(&mut self, v: bool) -> wasmtime::Result<()>25*112112d4SAlex Crichton fn set_continue(&mut self, v: bool) -> wasmtime::Result<()> { 26*112112d4SAlex Crichton self.continue_ = v; 27*112112d4SAlex Crichton Ok(()) 28*112112d4SAlex Crichton } 29*112112d4SAlex Crichton get_continue(&mut self) -> wasmtime::Result<bool>30*112112d4SAlex Crichton fn get_continue(&mut self) -> wasmtime::Result<bool> { 31*112112d4SAlex Crichton Ok(self.continue_) 32*112112d4SAlex Crichton } 33*112112d4SAlex Crichton } 34*112112d4SAlex Crichton 35*112112d4SAlex Crichton impl bindings::local::local::ready::HostThing for Ctx { new(&mut self) -> wasmtime::Result<Resource<Thing>>36*112112d4SAlex Crichton fn new(&mut self) -> wasmtime::Result<Resource<Thing>> { 37*112112d4SAlex Crichton Ok(self.table.push(Thing::default())?) 38*112112d4SAlex Crichton } 39*112112d4SAlex Crichton set_ready(&mut self, thing: Resource<Thing>, ready: bool) -> wasmtime::Result<()>40*112112d4SAlex Crichton fn set_ready(&mut self, thing: Resource<Thing>, ready: bool) -> wasmtime::Result<()> { 41*112112d4SAlex Crichton let thing = self.table.get(&thing)?; 42*112112d4SAlex Crichton let mut wakers = thing.wakers.lock().unwrap(); 43*112112d4SAlex Crichton if ready { 44*112112d4SAlex Crichton if let Some(wakers) = wakers.take() { 45*112112d4SAlex Crichton for waker in wakers { 46*112112d4SAlex Crichton waker.wake(); 47*112112d4SAlex Crichton } 48*112112d4SAlex Crichton } 49*112112d4SAlex Crichton } else if wakers.is_none() { 50*112112d4SAlex Crichton *wakers = Some(Vec::new()); 51*112112d4SAlex Crichton } 52*112112d4SAlex Crichton Ok(()) 53*112112d4SAlex Crichton } 54*112112d4SAlex Crichton drop(&mut self, thing: Resource<Thing>) -> wasmtime::Result<()>55*112112d4SAlex Crichton fn drop(&mut self, thing: Resource<Thing>) -> wasmtime::Result<()> { 56*112112d4SAlex Crichton self.table.delete(thing)?; 57*112112d4SAlex Crichton Ok(()) 58*112112d4SAlex Crichton } 59*112112d4SAlex Crichton } 60*112112d4SAlex Crichton 61*112112d4SAlex Crichton impl bindings::local::local::ready::HostThingWithStore for Ctx { when_ready<T>( accessor: &Accessor<T, Self>, thing: Resource<Thing>, ) -> wasmtime::Result<()>62*112112d4SAlex Crichton async fn when_ready<T>( 63*112112d4SAlex Crichton accessor: &Accessor<T, Self>, 64*112112d4SAlex Crichton thing: Resource<Thing>, 65*112112d4SAlex Crichton ) -> wasmtime::Result<()> { 66*112112d4SAlex Crichton let wakers = accessor.with(|mut view| { 67*112112d4SAlex Crichton Ok::<_, wasmtime::Error>(view.get().table.get(&thing)?.wakers.clone()) 68*112112d4SAlex Crichton })?; 69*112112d4SAlex Crichton 70*112112d4SAlex Crichton future::poll_fn(move |cx| { 71*112112d4SAlex Crichton let mut wakers = wakers.lock().unwrap(); 72*112112d4SAlex Crichton if let Some(wakers) = wakers.deref_mut() { 73*112112d4SAlex Crichton wakers.push(cx.waker().clone()); 74*112112d4SAlex Crichton Poll::Pending 75*112112d4SAlex Crichton } else { 76*112112d4SAlex Crichton Poll::Ready(()) 77*112112d4SAlex Crichton } 78*112112d4SAlex Crichton }) 79*112112d4SAlex Crichton .await; 80*112112d4SAlex Crichton 81*112112d4SAlex Crichton Ok(()) 82*112112d4SAlex Crichton } 83*112112d4SAlex Crichton } 84*112112d4SAlex Crichton 85*112112d4SAlex Crichton impl bindings::local::local::ready::Host for Ctx {} 86