lightning/util/
native_async.rs1#[cfg(all(test, feature = "std"))]
11use crate::sync::Mutex;
12use crate::util::async_poll::{MaybeSend, MaybeSync};
13
14#[cfg(all(test, not(feature = "std")))]
15use core::cell::RefCell;
16use core::future::Future;
17#[cfg(test)]
18use core::pin::Pin;
19
20pub trait FutureSpawner: MaybeSend + MaybeSync + 'static {
24 fn spawn<T: Future<Output = ()> + MaybeSend + 'static>(&self, future: T);
28}
29
30#[cfg(test)]
31trait MaybeSendableFuture: Future<Output = ()> + MaybeSend + 'static {}
32#[cfg(test)]
33impl<F: Future<Output = ()> + MaybeSend + 'static> MaybeSendableFuture for F {}
34
35#[cfg(all(test, feature = "std"))]
38pub(crate) struct FutureQueue(Mutex<Vec<Pin<Box<dyn MaybeSendableFuture>>>>);
39#[cfg(all(test, not(feature = "std")))]
40pub(crate) struct FutureQueue(RefCell<Vec<Pin<Box<dyn MaybeSendableFuture>>>>);
41
42#[cfg(test)]
43impl FutureQueue {
44 pub(crate) fn new() -> Self {
45 #[cfg(feature = "std")]
46 {
47 FutureQueue(Mutex::new(Vec::new()))
48 }
49 #[cfg(not(feature = "std"))]
50 {
51 FutureQueue(RefCell::new(Vec::new()))
52 }
53 }
54
55 pub(crate) fn pending_futures(&self) -> usize {
56 #[cfg(feature = "std")]
57 {
58 self.0.lock().unwrap().len()
59 }
60 #[cfg(not(feature = "std"))]
61 {
62 self.0.borrow().len()
63 }
64 }
65
66 pub(crate) fn poll_futures(&self) {
67 let mut futures;
68 #[cfg(feature = "std")]
69 {
70 futures = self.0.lock().unwrap();
71 }
72 #[cfg(not(feature = "std"))]
73 {
74 futures = self.0.borrow_mut();
75 }
76 futures.retain_mut(|fut| {
77 use core::task::{Context, Poll};
78 let waker = crate::util::async_poll::dummy_waker();
79 match fut.as_mut().poll(&mut Context::from_waker(&waker)) {
80 Poll::Ready(()) => false,
81 Poll::Pending => true,
82 }
83 });
84 }
85}
86
87#[cfg(test)]
88impl FutureSpawner for FutureQueue {
89 fn spawn<T: Future<Output = ()> + MaybeSend + 'static>(&self, future: T) {
90 #[cfg(feature = "std")]
91 {
92 self.0.lock().unwrap().push(Box::pin(future));
93 }
94 #[cfg(not(feature = "std"))]
95 {
96 self.0.borrow_mut().push(Box::pin(future));
97 }
98 }
99}
100
101#[cfg(test)]
102impl<D: core::ops::Deref<Target = FutureQueue> + MaybeSend + MaybeSync + 'static> FutureSpawner
103 for D
104{
105 fn spawn<T: Future<Output = ()> + MaybeSend + 'static>(&self, future: T) {
106 #[cfg(feature = "std")]
107 {
108 self.0.lock().unwrap().push(Box::pin(future));
109 }
110 #[cfg(not(feature = "std"))]
111 {
112 self.0.borrow_mut().push(Box::pin(future));
113 }
114 }
115}