1 mod bindings { 2 wit_bindgen::generate!({ 3 path: "../misc/component-async-tests/wit", 4 world: "backpressure-caller", 5 }); 6 7 use super::Component; 8 export!(Component); 9 } 10 11 use { 12 bindings::{ 13 exports::local::local::run::Guest, 14 local::local::{backpressure, run}, 15 }, 16 futures::future, 17 std::{ 18 future::Future, 19 pin::Pin, 20 task::{Context, Poll}, 21 }, 22 }; 23 24 struct Component; 25 26 impl Guest for Component { 27 async fn run() { 28 test( 29 || backpressure::set_backpressure(true), 30 || backpressure::set_backpressure(false), 31 ) 32 .await; 33 test( 34 || backpressure::inc_backpressure(), 35 || backpressure::dec_backpressure(), 36 ) 37 .await; 38 } 39 } 40 41 async fn test(enable: impl Fn(), disable: impl Fn()) { 42 enable(); 43 44 let mut a = Some(Box::pin(run::run())); 45 let mut b = Some(Box::pin(run::run())); 46 let mut c = Some(Box::pin(run::run())); 47 48 let mut backpressure_is_set = true; 49 future::poll_fn(move |cx| { 50 let a_ready = is_ready(cx, &mut a); 51 let b_ready = is_ready(cx, &mut b); 52 let c_ready = is_ready(cx, &mut c); 53 54 if backpressure_is_set { 55 assert!(!a_ready); 56 assert!(!b_ready); 57 assert!(!c_ready); 58 59 disable(); 60 backpressure_is_set = false; 61 62 Poll::Pending 63 } else if a_ready && b_ready && c_ready { 64 Poll::Ready(()) 65 } else { 66 Poll::Pending 67 } 68 }) 69 .await 70 } 71 72 fn is_ready(cx: &mut Context, fut: &mut Option<Pin<Box<impl Future<Output = ()>>>>) -> bool { 73 if let Some(v) = fut.as_mut() { 74 if v.as_mut().poll(cx).is_ready() { 75 *fut = None; 76 true 77 } else { 78 false 79 } 80 } else { 81 true 82 } 83 } 84 85 // Unused function; required since this file is built as a `bin`: 86 fn main() {} 87