1*5225e6b1SAndroid Build Coastguard Worker // Copyright 2024, The Android Open Source Project
2*5225e6b1SAndroid Build Coastguard Worker //
3*5225e6b1SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*5225e6b1SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*5225e6b1SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*5225e6b1SAndroid Build Coastguard Worker //
7*5225e6b1SAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0
8*5225e6b1SAndroid Build Coastguard Worker //
9*5225e6b1SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*5225e6b1SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*5225e6b1SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*5225e6b1SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*5225e6b1SAndroid Build Coastguard Worker // limitations under the License.
14*5225e6b1SAndroid Build Coastguard Worker
15*5225e6b1SAndroid Build Coastguard Worker //! This file provides async utility APIs used by GBL.
16*5225e6b1SAndroid Build Coastguard Worker //!
17*5225e6b1SAndroid Build Coastguard Worker //! They are mainly barebone APIs for busy waiting and polling Futures. There is no support for
18*5225e6b1SAndroid Build Coastguard Worker //! sleep/wake or threading.
19*5225e6b1SAndroid Build Coastguard Worker
20*5225e6b1SAndroid Build Coastguard Worker #![cfg_attr(not(test), no_std)]
21*5225e6b1SAndroid Build Coastguard Worker
22*5225e6b1SAndroid Build Coastguard Worker use core::{
23*5225e6b1SAndroid Build Coastguard Worker future::Future,
24*5225e6b1SAndroid Build Coastguard Worker ops::DerefMut,
25*5225e6b1SAndroid Build Coastguard Worker pin::{pin, Pin},
26*5225e6b1SAndroid Build Coastguard Worker ptr::null,
27*5225e6b1SAndroid Build Coastguard Worker task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
28*5225e6b1SAndroid Build Coastguard Worker };
29*5225e6b1SAndroid Build Coastguard Worker
30*5225e6b1SAndroid Build Coastguard Worker /// Clone method for `NOOP_VTABLE`.
noop_clone(_: *const ()) -> RawWaker31*5225e6b1SAndroid Build Coastguard Worker fn noop_clone(_: *const ()) -> RawWaker {
32*5225e6b1SAndroid Build Coastguard Worker noop_raw_waker()
33*5225e6b1SAndroid Build Coastguard Worker }
34*5225e6b1SAndroid Build Coastguard Worker
35*5225e6b1SAndroid Build Coastguard Worker /// Noop method for `wake`, `wake_by_ref` and `drop` in `RawWakerVTable`.
noop_wake_method(_: *const ())36*5225e6b1SAndroid Build Coastguard Worker fn noop_wake_method(_: *const ()) {}
37*5225e6b1SAndroid Build Coastguard Worker
38*5225e6b1SAndroid Build Coastguard Worker /// A noop `RawWakerVTable`
39*5225e6b1SAndroid Build Coastguard Worker const NOOP_VTABLE: RawWakerVTable =
40*5225e6b1SAndroid Build Coastguard Worker RawWakerVTable::new(noop_clone, noop_wake_method, noop_wake_method, noop_wake_method);
41*5225e6b1SAndroid Build Coastguard Worker
42*5225e6b1SAndroid Build Coastguard Worker /// Creates a noop instance that does nothing.
noop_raw_waker() -> RawWaker43*5225e6b1SAndroid Build Coastguard Worker fn noop_raw_waker() -> RawWaker {
44*5225e6b1SAndroid Build Coastguard Worker RawWaker::new(null(), &NOOP_VTABLE)
45*5225e6b1SAndroid Build Coastguard Worker }
46*5225e6b1SAndroid Build Coastguard Worker
47*5225e6b1SAndroid Build Coastguard Worker /// Repetitively polls and blocks until a future completes.
block_on<O>(fut: impl Future<Output = O>) -> O48*5225e6b1SAndroid Build Coastguard Worker pub fn block_on<O>(fut: impl Future<Output = O>) -> O {
49*5225e6b1SAndroid Build Coastguard Worker let mut fut = pin!(fut);
50*5225e6b1SAndroid Build Coastguard Worker loop {
51*5225e6b1SAndroid Build Coastguard Worker match poll(&mut fut) {
52*5225e6b1SAndroid Build Coastguard Worker Some(res) => return res,
53*5225e6b1SAndroid Build Coastguard Worker _ => {}
54*5225e6b1SAndroid Build Coastguard Worker }
55*5225e6b1SAndroid Build Coastguard Worker }
56*5225e6b1SAndroid Build Coastguard Worker }
57*5225e6b1SAndroid Build Coastguard Worker
58*5225e6b1SAndroid Build Coastguard Worker /// Polls a Future.
59*5225e6b1SAndroid Build Coastguard Worker ///
60*5225e6b1SAndroid Build Coastguard Worker /// Returns Some(_) if ready, None otherwise.
poll<O, F: Future<Output = O> + ?Sized>( fut: &mut Pin<impl DerefMut<Target = F>>, ) -> Option<O>61*5225e6b1SAndroid Build Coastguard Worker pub fn poll<O, F: Future<Output = O> + ?Sized>(
62*5225e6b1SAndroid Build Coastguard Worker fut: &mut Pin<impl DerefMut<Target = F>>,
63*5225e6b1SAndroid Build Coastguard Worker ) -> Option<O> {
64*5225e6b1SAndroid Build Coastguard Worker // SAFETY:
65*5225e6b1SAndroid Build Coastguard Worker // * All methods for noop_raw_waker() are either noop or have no shared state. Thus they are
66*5225e6b1SAndroid Build Coastguard Worker // thread-safe.
67*5225e6b1SAndroid Build Coastguard Worker let waker = unsafe { Waker::from_raw(noop_raw_waker()) };
68*5225e6b1SAndroid Build Coastguard Worker let mut context = Context::from_waker(&waker);
69*5225e6b1SAndroid Build Coastguard Worker match fut.as_mut().poll(&mut context) {
70*5225e6b1SAndroid Build Coastguard Worker Poll::Pending => None,
71*5225e6b1SAndroid Build Coastguard Worker Poll::Ready(res) => Some(res),
72*5225e6b1SAndroid Build Coastguard Worker }
73*5225e6b1SAndroid Build Coastguard Worker }
74*5225e6b1SAndroid Build Coastguard Worker
75*5225e6b1SAndroid Build Coastguard Worker /// Polls the given future for up to `n` times.
poll_n_times<O, F: Future<Output = O> + ?Sized>( fut: &mut Pin<impl DerefMut<Target = F>>, n: usize, ) -> Option<O>76*5225e6b1SAndroid Build Coastguard Worker pub fn poll_n_times<O, F: Future<Output = O> + ?Sized>(
77*5225e6b1SAndroid Build Coastguard Worker fut: &mut Pin<impl DerefMut<Target = F>>,
78*5225e6b1SAndroid Build Coastguard Worker n: usize,
79*5225e6b1SAndroid Build Coastguard Worker ) -> Option<O> {
80*5225e6b1SAndroid Build Coastguard Worker (0..n).find_map(|_| poll(fut))
81*5225e6b1SAndroid Build Coastguard Worker }
82*5225e6b1SAndroid Build Coastguard Worker
83*5225e6b1SAndroid Build Coastguard Worker /// `Yield` implements a simple API for yielding control once to the executor.
84*5225e6b1SAndroid Build Coastguard Worker struct Yield(bool);
85*5225e6b1SAndroid Build Coastguard Worker
86*5225e6b1SAndroid Build Coastguard Worker impl Future for Yield {
87*5225e6b1SAndroid Build Coastguard Worker type Output = ();
88*5225e6b1SAndroid Build Coastguard Worker
poll(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output>89*5225e6b1SAndroid Build Coastguard Worker fn poll(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output> {
90*5225e6b1SAndroid Build Coastguard Worker self.0 = !self.0;
91*5225e6b1SAndroid Build Coastguard Worker match self.0 {
92*5225e6b1SAndroid Build Coastguard Worker true => Poll::Pending,
93*5225e6b1SAndroid Build Coastguard Worker _ => Poll::Ready(()),
94*5225e6b1SAndroid Build Coastguard Worker }
95*5225e6b1SAndroid Build Coastguard Worker }
96*5225e6b1SAndroid Build Coastguard Worker }
97*5225e6b1SAndroid Build Coastguard Worker
98*5225e6b1SAndroid Build Coastguard Worker /// Yield the execution once.
yield_now()99*5225e6b1SAndroid Build Coastguard Worker pub async fn yield_now() {
100*5225e6b1SAndroid Build Coastguard Worker Yield(false).await
101*5225e6b1SAndroid Build Coastguard Worker }
102*5225e6b1SAndroid Build Coastguard Worker
103*5225e6b1SAndroid Build Coastguard Worker /// `YieldCounter` maintains a counter and yield control to executor once it overflows a given
104*5225e6b1SAndroid Build Coastguard Worker /// threshold. When overflow occurs, the counter value is reset and the carry over is discarded.
105*5225e6b1SAndroid Build Coastguard Worker pub struct YieldCounter {
106*5225e6b1SAndroid Build Coastguard Worker threshold: u64,
107*5225e6b1SAndroid Build Coastguard Worker current: u64,
108*5225e6b1SAndroid Build Coastguard Worker }
109*5225e6b1SAndroid Build Coastguard Worker
110*5225e6b1SAndroid Build Coastguard Worker impl YieldCounter {
111*5225e6b1SAndroid Build Coastguard Worker /// Creates an instance with a given threshold.
new(threshold: u64) -> Self112*5225e6b1SAndroid Build Coastguard Worker pub fn new(threshold: u64) -> Self {
113*5225e6b1SAndroid Build Coastguard Worker Self { threshold, current: 0 }
114*5225e6b1SAndroid Build Coastguard Worker }
115*5225e6b1SAndroid Build Coastguard Worker
116*5225e6b1SAndroid Build Coastguard Worker /// Increments the current counter and yield execution if the value overflows the threshold.
increment(&mut self, inc: u64)117*5225e6b1SAndroid Build Coastguard Worker pub async fn increment(&mut self, inc: u64) {
118*5225e6b1SAndroid Build Coastguard Worker self.current = self.current.saturating_sub(inc);
119*5225e6b1SAndroid Build Coastguard Worker if self.current == 0 {
120*5225e6b1SAndroid Build Coastguard Worker self.current = self.threshold;
121*5225e6b1SAndroid Build Coastguard Worker yield_now().await;
122*5225e6b1SAndroid Build Coastguard Worker }
123*5225e6b1SAndroid Build Coastguard Worker }
124*5225e6b1SAndroid Build Coastguard Worker }
125*5225e6b1SAndroid Build Coastguard Worker
126*5225e6b1SAndroid Build Coastguard Worker /// Repetitively polls two futures until both of them finish.
join<L, LO, R, RO>(fut_lhs: L, fut_rhs: R) -> (LO, RO) where L: Future<Output = LO>, R: Future<Output = RO>,127*5225e6b1SAndroid Build Coastguard Worker pub async fn join<L, LO, R, RO>(fut_lhs: L, fut_rhs: R) -> (LO, RO)
128*5225e6b1SAndroid Build Coastguard Worker where
129*5225e6b1SAndroid Build Coastguard Worker L: Future<Output = LO>,
130*5225e6b1SAndroid Build Coastguard Worker R: Future<Output = RO>,
131*5225e6b1SAndroid Build Coastguard Worker {
132*5225e6b1SAndroid Build Coastguard Worker let fut_lhs = &mut pin!(fut_lhs);
133*5225e6b1SAndroid Build Coastguard Worker let fut_rhs = &mut pin!(fut_rhs);
134*5225e6b1SAndroid Build Coastguard Worker let mut out_lhs = poll(fut_lhs);
135*5225e6b1SAndroid Build Coastguard Worker let mut out_rhs = poll(fut_rhs);
136*5225e6b1SAndroid Build Coastguard Worker while out_lhs.is_none() || out_rhs.is_none() {
137*5225e6b1SAndroid Build Coastguard Worker yield_now().await;
138*5225e6b1SAndroid Build Coastguard Worker if out_lhs.is_none() {
139*5225e6b1SAndroid Build Coastguard Worker out_lhs = poll(fut_lhs);
140*5225e6b1SAndroid Build Coastguard Worker }
141*5225e6b1SAndroid Build Coastguard Worker
142*5225e6b1SAndroid Build Coastguard Worker if out_rhs.is_none() {
143*5225e6b1SAndroid Build Coastguard Worker out_rhs = poll(fut_rhs);
144*5225e6b1SAndroid Build Coastguard Worker }
145*5225e6b1SAndroid Build Coastguard Worker }
146*5225e6b1SAndroid Build Coastguard Worker (out_lhs.unwrap(), out_rhs.unwrap())
147*5225e6b1SAndroid Build Coastguard Worker }
148*5225e6b1SAndroid Build Coastguard Worker
149*5225e6b1SAndroid Build Coastguard Worker /// Waits until either of the given two futures completes.
select<L, LO, R, RO>(fut_lhs: L, fut_rhs: R) -> (Option<LO>, Option<RO>) where L: Future<Output = LO>, R: Future<Output = RO>,150*5225e6b1SAndroid Build Coastguard Worker pub async fn select<L, LO, R, RO>(fut_lhs: L, fut_rhs: R) -> (Option<LO>, Option<RO>)
151*5225e6b1SAndroid Build Coastguard Worker where
152*5225e6b1SAndroid Build Coastguard Worker L: Future<Output = LO>,
153*5225e6b1SAndroid Build Coastguard Worker R: Future<Output = RO>,
154*5225e6b1SAndroid Build Coastguard Worker {
155*5225e6b1SAndroid Build Coastguard Worker let fut_lhs = &mut pin!(fut_lhs);
156*5225e6b1SAndroid Build Coastguard Worker let fut_rhs = &mut pin!(fut_rhs);
157*5225e6b1SAndroid Build Coastguard Worker let mut out_lhs = poll(fut_lhs);
158*5225e6b1SAndroid Build Coastguard Worker let mut out_rhs = poll(fut_rhs);
159*5225e6b1SAndroid Build Coastguard Worker while out_lhs.is_none() && out_rhs.is_none() {
160*5225e6b1SAndroid Build Coastguard Worker yield_now().await;
161*5225e6b1SAndroid Build Coastguard Worker out_lhs = poll(fut_lhs);
162*5225e6b1SAndroid Build Coastguard Worker out_rhs = poll(fut_rhs);
163*5225e6b1SAndroid Build Coastguard Worker }
164*5225e6b1SAndroid Build Coastguard Worker (out_lhs, out_rhs)
165*5225e6b1SAndroid Build Coastguard Worker }
166*5225e6b1SAndroid Build Coastguard Worker
167*5225e6b1SAndroid Build Coastguard Worker /// Runs a [Future] and checks and asserts that it returns eventually.
assert_return<O>(fut: impl Future<Output = O>) -> O168*5225e6b1SAndroid Build Coastguard Worker pub async fn assert_return<O>(fut: impl Future<Output = O>) -> O {
169*5225e6b1SAndroid Build Coastguard Worker struct Returned(bool);
170*5225e6b1SAndroid Build Coastguard Worker
171*5225e6b1SAndroid Build Coastguard Worker impl Drop for Returned {
172*5225e6b1SAndroid Build Coastguard Worker fn drop(&mut self) {
173*5225e6b1SAndroid Build Coastguard Worker assert!(self.0)
174*5225e6b1SAndroid Build Coastguard Worker }
175*5225e6b1SAndroid Build Coastguard Worker }
176*5225e6b1SAndroid Build Coastguard Worker
177*5225e6b1SAndroid Build Coastguard Worker let mut flag = Returned(false);
178*5225e6b1SAndroid Build Coastguard Worker let res = fut.await;
179*5225e6b1SAndroid Build Coastguard Worker flag.0 = true;
180*5225e6b1SAndroid Build Coastguard Worker res
181*5225e6b1SAndroid Build Coastguard Worker }
182*5225e6b1SAndroid Build Coastguard Worker
183*5225e6b1SAndroid Build Coastguard Worker #[cfg(test)]
184*5225e6b1SAndroid Build Coastguard Worker mod test {
185*5225e6b1SAndroid Build Coastguard Worker use super::*;
186*5225e6b1SAndroid Build Coastguard Worker use std::sync::Mutex;
187*5225e6b1SAndroid Build Coastguard Worker
188*5225e6b1SAndroid Build Coastguard Worker #[test]
test()189*5225e6b1SAndroid Build Coastguard Worker fn test() {
190*5225e6b1SAndroid Build Coastguard Worker let mut counter = YieldCounter::new(1);
191*5225e6b1SAndroid Build Coastguard Worker let mut fut = pin!(async move {
192*5225e6b1SAndroid Build Coastguard Worker counter.increment(2).await;
193*5225e6b1SAndroid Build Coastguard Worker counter.increment(2).await;
194*5225e6b1SAndroid Build Coastguard Worker });
195*5225e6b1SAndroid Build Coastguard Worker
196*5225e6b1SAndroid Build Coastguard Worker assert!(poll(&mut fut).is_none());
197*5225e6b1SAndroid Build Coastguard Worker assert!(poll(&mut fut).is_none());
198*5225e6b1SAndroid Build Coastguard Worker assert!(poll(&mut fut).is_some());
199*5225e6b1SAndroid Build Coastguard Worker }
200*5225e6b1SAndroid Build Coastguard Worker
201*5225e6b1SAndroid Build Coastguard Worker #[test]
test_join()202*5225e6b1SAndroid Build Coastguard Worker fn test_join() {
203*5225e6b1SAndroid Build Coastguard Worker let val1 = Mutex::new(0);
204*5225e6b1SAndroid Build Coastguard Worker let val2 = Mutex::new(1);
205*5225e6b1SAndroid Build Coastguard Worker
206*5225e6b1SAndroid Build Coastguard Worker let mut join_fut = pin!(join(
207*5225e6b1SAndroid Build Coastguard Worker async {
208*5225e6b1SAndroid Build Coastguard Worker *val1.try_lock().unwrap() += 1;
209*5225e6b1SAndroid Build Coastguard Worker yield_now().await;
210*5225e6b1SAndroid Build Coastguard Worker *val1.try_lock().unwrap() += 1;
211*5225e6b1SAndroid Build Coastguard Worker yield_now().await;
212*5225e6b1SAndroid Build Coastguard Worker },
213*5225e6b1SAndroid Build Coastguard Worker async {
214*5225e6b1SAndroid Build Coastguard Worker *val2.try_lock().unwrap() += 1;
215*5225e6b1SAndroid Build Coastguard Worker yield_now().await;
216*5225e6b1SAndroid Build Coastguard Worker *val2.try_lock().unwrap() += 1;
217*5225e6b1SAndroid Build Coastguard Worker yield_now().await;
218*5225e6b1SAndroid Build Coastguard Worker *val2.try_lock().unwrap() += 1;
219*5225e6b1SAndroid Build Coastguard Worker yield_now().await;
220*5225e6b1SAndroid Build Coastguard Worker }
221*5225e6b1SAndroid Build Coastguard Worker ));
222*5225e6b1SAndroid Build Coastguard Worker
223*5225e6b1SAndroid Build Coastguard Worker assert!(poll(&mut join_fut).is_none());
224*5225e6b1SAndroid Build Coastguard Worker assert_eq!(*val1.try_lock().unwrap(), 1);
225*5225e6b1SAndroid Build Coastguard Worker assert_eq!(*val2.try_lock().unwrap(), 2);
226*5225e6b1SAndroid Build Coastguard Worker
227*5225e6b1SAndroid Build Coastguard Worker assert!(poll(&mut join_fut).is_none());
228*5225e6b1SAndroid Build Coastguard Worker assert_eq!(*val1.try_lock().unwrap(), 2);
229*5225e6b1SAndroid Build Coastguard Worker assert_eq!(*val2.try_lock().unwrap(), 3);
230*5225e6b1SAndroid Build Coastguard Worker
231*5225e6b1SAndroid Build Coastguard Worker assert!(poll(&mut join_fut).is_none());
232*5225e6b1SAndroid Build Coastguard Worker assert_eq!(*val1.try_lock().unwrap(), 2);
233*5225e6b1SAndroid Build Coastguard Worker assert_eq!(*val2.try_lock().unwrap(), 4);
234*5225e6b1SAndroid Build Coastguard Worker
235*5225e6b1SAndroid Build Coastguard Worker assert!(poll(&mut join_fut).is_some());
236*5225e6b1SAndroid Build Coastguard Worker }
237*5225e6b1SAndroid Build Coastguard Worker
238*5225e6b1SAndroid Build Coastguard Worker #[test]
test_select()239*5225e6b1SAndroid Build Coastguard Worker fn test_select() {
240*5225e6b1SAndroid Build Coastguard Worker let val1 = Mutex::new(0);
241*5225e6b1SAndroid Build Coastguard Worker let val2 = Mutex::new(1);
242*5225e6b1SAndroid Build Coastguard Worker
243*5225e6b1SAndroid Build Coastguard Worker let mut select_fut = pin!(select(
244*5225e6b1SAndroid Build Coastguard Worker async {
245*5225e6b1SAndroid Build Coastguard Worker *val1.try_lock().unwrap() += 1;
246*5225e6b1SAndroid Build Coastguard Worker yield_now().await;
247*5225e6b1SAndroid Build Coastguard Worker *val1.try_lock().unwrap() += 1;
248*5225e6b1SAndroid Build Coastguard Worker yield_now().await;
249*5225e6b1SAndroid Build Coastguard Worker },
250*5225e6b1SAndroid Build Coastguard Worker async {
251*5225e6b1SAndroid Build Coastguard Worker *val2.try_lock().unwrap() += 1;
252*5225e6b1SAndroid Build Coastguard Worker yield_now().await;
253*5225e6b1SAndroid Build Coastguard Worker *val2.try_lock().unwrap() += 1;
254*5225e6b1SAndroid Build Coastguard Worker yield_now().await;
255*5225e6b1SAndroid Build Coastguard Worker *val2.try_lock().unwrap() += 1;
256*5225e6b1SAndroid Build Coastguard Worker yield_now().await;
257*5225e6b1SAndroid Build Coastguard Worker }
258*5225e6b1SAndroid Build Coastguard Worker ));
259*5225e6b1SAndroid Build Coastguard Worker
260*5225e6b1SAndroid Build Coastguard Worker assert!(poll(&mut select_fut).is_none());
261*5225e6b1SAndroid Build Coastguard Worker assert_eq!(*val1.try_lock().unwrap(), 1);
262*5225e6b1SAndroid Build Coastguard Worker assert_eq!(*val2.try_lock().unwrap(), 2);
263*5225e6b1SAndroid Build Coastguard Worker
264*5225e6b1SAndroid Build Coastguard Worker assert!(poll(&mut select_fut).is_none());
265*5225e6b1SAndroid Build Coastguard Worker assert_eq!(*val1.try_lock().unwrap(), 2);
266*5225e6b1SAndroid Build Coastguard Worker assert_eq!(*val2.try_lock().unwrap(), 3);
267*5225e6b1SAndroid Build Coastguard Worker
268*5225e6b1SAndroid Build Coastguard Worker let (lhs, rhs) = poll(&mut select_fut).unwrap();
269*5225e6b1SAndroid Build Coastguard Worker assert!(lhs.is_some());
270*5225e6b1SAndroid Build Coastguard Worker assert!(rhs.is_none());
271*5225e6b1SAndroid Build Coastguard Worker }
272*5225e6b1SAndroid Build Coastguard Worker
273*5225e6b1SAndroid Build Coastguard Worker #[test]
test_assert_return()274*5225e6b1SAndroid Build Coastguard Worker fn test_assert_return() {
275*5225e6b1SAndroid Build Coastguard Worker // Finishes. No assert.
276*5225e6b1SAndroid Build Coastguard Worker block_on(assert_return(async { yield_now().await }));
277*5225e6b1SAndroid Build Coastguard Worker }
278*5225e6b1SAndroid Build Coastguard Worker
279*5225e6b1SAndroid Build Coastguard Worker #[test]
280*5225e6b1SAndroid Build Coastguard Worker #[should_panic]
test_assert_return_panics()281*5225e6b1SAndroid Build Coastguard Worker fn test_assert_return_panics() {
282*5225e6b1SAndroid Build Coastguard Worker let mut fut = pin!(assert_return(async { yield_now().await }));
283*5225e6b1SAndroid Build Coastguard Worker // Need one more poll to finish. Thus it should panic when going out of scope.
284*5225e6b1SAndroid Build Coastguard Worker assert!(poll(&mut fut).is_none());
285*5225e6b1SAndroid Build Coastguard Worker }
286*5225e6b1SAndroid Build Coastguard Worker }
287