7
7
//! This module contains a few public utility which are used to run LDK in a native Rust async
8
8
//! environment.
9
9
10
+ #[ cfg( all( test, feature = "std" ) ) ]
11
+ use crate :: sync:: Mutex ;
10
12
use crate :: util:: async_poll:: { MaybeSend , MaybeSync } ;
11
13
14
+ #[ cfg( all( test, not( feature = "std" ) ) ) ]
15
+ use core:: cell:: RefCell ;
12
16
use core:: future:: Future ;
17
+ #[ cfg( test) ]
18
+ use core:: pin:: Pin ;
13
19
14
20
/// A generic trait which is able to spawn futures in the background.
15
21
pub trait FutureSpawner : MaybeSend + MaybeSync + ' static {
@@ -18,3 +24,81 @@ pub trait FutureSpawner: MaybeSend + MaybeSync + 'static {
18
24
/// This method MUST NOT block on the given future immediately.
19
25
fn spawn < T : Future < Output = ( ) > + MaybeSend + ' static > ( & self , future : T ) ;
20
26
}
27
+
28
+ #[ cfg( test) ]
29
+ trait MaybeSendableFuture : Future < Output = ( ) > + MaybeSend + ' static { }
30
+ #[ cfg( test) ]
31
+ impl < F : Future < Output = ( ) > + MaybeSend + ' static > MaybeSendableFuture for F { }
32
+
33
+ /// A simple [`FutureSpawner`] which holds [`Future`]s until they are manually polled via
34
+ /// [`Self::poll_futures`].
35
+ #[ cfg( all( test, feature = "std" ) ) ]
36
+ pub ( crate ) struct FutureQueue ( Mutex < Vec < Pin < Box < dyn MaybeSendableFuture > > > > ) ;
37
+ #[ cfg( all( test, not( feature = "std" ) ) ) ]
38
+ pub ( crate ) struct FutureQueue ( RefCell < Vec < Pin < Box < dyn MaybeSendableFuture > > > > ) ;
39
+
40
+ #[ cfg( test) ]
41
+ impl FutureQueue {
42
+ pub ( crate ) fn new ( ) -> Self {
43
+ FutureQueue ( Mutex :: new ( Vec :: new ( ) ) )
44
+ }
45
+
46
+ pub ( crate ) fn pending_futures ( & self ) -> usize {
47
+ #[ cfg( feature = "std" ) ]
48
+ {
49
+ self . 0 . lock ( ) . unwrap ( ) . len ( )
50
+ }
51
+ #[ cfg( not( feature = "std" ) ) ]
52
+ {
53
+ self . 0 . borrow ( ) . len ( )
54
+ }
55
+ }
56
+
57
+ pub ( crate ) fn poll_futures ( & self ) {
58
+ let mut futures;
59
+ #[ cfg( feature = "std" ) ]
60
+ {
61
+ futures = self . 0 . lock ( ) . unwrap ( ) ;
62
+ }
63
+ #[ cfg( not( feature = "std" ) ) ]
64
+ {
65
+ futures = self . 0 . borrow_mut ( ) ;
66
+ }
67
+ futures. retain_mut ( |fut| {
68
+ use core:: task:: { Context , Poll } ;
69
+ let waker = crate :: util:: async_poll:: dummy_waker ( ) ;
70
+ match fut. as_mut ( ) . poll ( & mut Context :: from_waker ( & waker) ) {
71
+ Poll :: Ready ( ( ) ) => false ,
72
+ Poll :: Pending => true ,
73
+ }
74
+ } ) ;
75
+ }
76
+ }
77
+
78
+ #[ cfg( test) ]
79
+ impl FutureSpawner for FutureQueue {
80
+ fn spawn < T : Future < Output = ( ) > + MaybeSend + ' static > ( & self , future : T ) {
81
+ #[ cfg( feature = "std" ) ]
82
+ {
83
+ self . 0 . lock ( ) . unwrap ( ) . push ( Box :: pin ( future) ) ;
84
+ }
85
+ #[ cfg( not( feature = "std" ) ) ]
86
+ {
87
+ self . 0 . borrow_mut ( ) . push ( Box :: pin ( future) ) ;
88
+ }
89
+ }
90
+ }
91
+
92
+ #[ cfg( test) ]
93
+ impl < D : core:: ops:: Deref < Target = FutureQueue > + Send + Sync + ' static > FutureSpawner for D {
94
+ fn spawn < T : Future < Output = ( ) > + MaybeSend + ' static > ( & self , future : T ) {
95
+ #[ cfg( feature = "std" ) ]
96
+ {
97
+ self . 0 . lock ( ) . unwrap ( ) . push ( Box :: pin ( future) ) ;
98
+ }
99
+ #[ cfg( not( feature = "std" ) ) ]
100
+ {
101
+ self . 0 . borrow_mut ( ) . push ( Box :: pin ( future) ) ;
102
+ }
103
+ }
104
+ }
0 commit comments