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 {
run()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 
test(enable: impl Fn(), disable: impl Fn())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 
is_ready(cx: &mut Context, fut: &mut Option<Pin<Box<impl Future<Output = ()>>>>) -> bool72 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`:
main()86 fn main() {}
87