@@ -4,9 +4,10 @@ use std::{
4
4
future:: Future ,
5
5
pin:: Pin ,
6
6
task:: { Context , Poll } ,
7
+ time:: { Duration , Instant } ,
7
8
} ;
8
9
9
- use hyper:: rt:: Executor ;
10
+ use hyper:: rt:: { Executor , Sleep , Timer } ;
10
11
use pin_project_lite:: pin_project;
11
12
12
13
/// Future executor that utilises `tokio` threads.
@@ -24,6 +25,21 @@ pin_project! {
24
25
}
25
26
}
26
27
28
+ /// A Timer that uses the tokio runtime.
29
+ #[ non_exhaustive]
30
+ #[ derive( Default , Clone , Debug ) ]
31
+ pub struct TokioTimer ;
32
+
33
+ // Use TokioSleep to get tokio::time::Sleep to implement Unpin.
34
+ // see https://docs.rs/tokio/latest/tokio/time/struct.Sleep.html
35
+ pin_project ! {
36
+ #[ derive( Debug ) ]
37
+ struct TokioSleep {
38
+ #[ pin]
39
+ inner: tokio:: time:: Sleep ,
40
+ }
41
+ }
42
+
27
43
// ===== impl TokioExecutor =====
28
44
29
45
impl < Fut > Executor < Fut > for TokioExecutor
@@ -190,6 +206,51 @@ where
190
206
}
191
207
}
192
208
209
+ // ==== impl TokioTimer =====
210
+
211
+ impl Timer for TokioTimer {
212
+ fn sleep ( & self , duration : Duration ) -> Pin < Box < dyn Sleep > > {
213
+ Box :: pin ( TokioSleep {
214
+ inner : tokio:: time:: sleep ( duration) ,
215
+ } )
216
+ }
217
+
218
+ fn sleep_until ( & self , deadline : Instant ) -> Pin < Box < dyn Sleep > > {
219
+ Box :: pin ( TokioSleep {
220
+ inner : tokio:: time:: sleep_until ( deadline. into ( ) ) ,
221
+ } )
222
+ }
223
+
224
+ fn reset ( & self , sleep : & mut Pin < Box < dyn Sleep > > , new_deadline : Instant ) {
225
+ if let Some ( sleep) = sleep. as_mut ( ) . downcast_mut_pin :: < TokioSleep > ( ) {
226
+ sleep. reset ( new_deadline)
227
+ }
228
+ }
229
+ }
230
+
231
+ impl TokioTimer {
232
+ /// Create a new TokioTimer
233
+ pub fn new ( ) -> Self {
234
+ Self { }
235
+ }
236
+ }
237
+
238
+ impl Future for TokioSleep {
239
+ type Output = ( ) ;
240
+
241
+ fn poll ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
242
+ self . project ( ) . inner . poll ( cx)
243
+ }
244
+ }
245
+
246
+ impl Sleep for TokioSleep { }
247
+
248
+ impl TokioSleep {
249
+ fn reset ( self : Pin < & mut Self > , deadline : Instant ) {
250
+ self . project ( ) . inner . as_mut ( ) . reset ( deadline. into ( ) ) ;
251
+ }
252
+ }
253
+
193
254
#[ cfg( test) ]
194
255
mod tests {
195
256
use crate :: rt:: TokioExecutor ;
0 commit comments