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