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,90 @@ 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
+ #[ cfg( feature = "std" ) ]
44
+ {
45
+ FutureQueue ( Mutex :: new ( Vec :: new ( ) ) )
46
+ }
47
+ #[ cfg( not( feature = "std" ) ) ]
48
+ {
49
+ FutureQueue ( RefCell :: new ( Vec :: new ( ) ) )
50
+ }
51
+ }
52
+
53
+ pub ( crate ) fn pending_futures ( & self ) -> usize {
54
+ #[ cfg( feature = "std" ) ]
55
+ {
56
+ self . 0 . lock ( ) . unwrap ( ) . len ( )
57
+ }
58
+ #[ cfg( not( feature = "std" ) ) ]
59
+ {
60
+ self . 0 . borrow ( ) . len ( )
61
+ }
62
+ }
63
+
64
+ pub ( crate ) fn poll_futures ( & self ) {
65
+ let mut futures;
66
+ #[ cfg( feature = "std" ) ]
67
+ {
68
+ futures = self . 0 . lock ( ) . unwrap ( ) ;
69
+ }
70
+ #[ cfg( not( feature = "std" ) ) ]
71
+ {
72
+ futures = self . 0 . borrow_mut ( ) ;
73
+ }
74
+ futures. retain_mut ( |fut| {
75
+ use core:: task:: { Context , Poll } ;
76
+ let waker = crate :: util:: async_poll:: dummy_waker ( ) ;
77
+ match fut. as_mut ( ) . poll ( & mut Context :: from_waker ( & waker) ) {
78
+ Poll :: Ready ( ( ) ) => false ,
79
+ Poll :: Pending => true ,
80
+ }
81
+ } ) ;
82
+ }
83
+ }
84
+
85
+ #[ cfg( test) ]
86
+ impl FutureSpawner for FutureQueue {
87
+ fn spawn < T : Future < Output = ( ) > + MaybeSend + ' static > ( & self , future : T ) {
88
+ #[ cfg( feature = "std" ) ]
89
+ {
90
+ self . 0 . lock ( ) . unwrap ( ) . push ( Box :: pin ( future) ) ;
91
+ }
92
+ #[ cfg( not( feature = "std" ) ) ]
93
+ {
94
+ self . 0 . borrow_mut ( ) . push ( Box :: pin ( future) ) ;
95
+ }
96
+ }
97
+ }
98
+
99
+ #[ cfg( test) ]
100
+ impl < D : core:: ops:: Deref < Target = FutureQueue > + MaybeSend + MaybeSync + ' static > FutureSpawner
101
+ for D
102
+ {
103
+ fn spawn < T : Future < Output = ( ) > + MaybeSend + ' static > ( & self , future : T ) {
104
+ #[ cfg( feature = "std" ) ]
105
+ {
106
+ self . 0 . lock ( ) . unwrap ( ) . push ( Box :: pin ( future) ) ;
107
+ }
108
+ #[ cfg( not( feature = "std" ) ) ]
109
+ {
110
+ self . 0 . borrow_mut ( ) . push ( Box :: pin ( future) ) ;
111
+ }
112
+ }
113
+ }
0 commit comments