@@ -17,29 +17,43 @@ use std::{
1717 task:: { Context , Poll } ,
1818 time:: { Duration , Instant } ,
1919} ;
20- use tokio:: { net:: TcpStream , runtime:: Handle } ;
20+ use tokio:: {
21+ net:: TcpStream ,
22+ runtime:: { EnterGuard , Handle , Runtime as TokioRT } ,
23+ } ;
2124use tokio_stream:: { StreamExt , wrappers:: IntervalStream } ;
2225use tokio_util:: compat:: { Compat , TokioAsyncReadCompatExt } ;
2326
2427/// Type alias for the tokio runtime
2528pub type TokioRuntime = Runtime < Tokio > ;
2629
2730impl TokioRuntime {
31+ /// Create a new TokioRuntime and bind it to this tokio runtime.
32+ pub fn tokio ( ) -> io:: Result < Self > {
33+ Ok ( Self :: tokio_with_runtime ( TokioRT :: new ( ) ?) )
34+ }
35+
2836 /// Create a new TokioRuntime and bind it to the current tokio runtime by default.
29- pub fn tokio ( ) -> Self {
37+ pub fn tokio_current ( ) -> Self {
3038 Self :: new ( Tokio :: current ( ) )
3139 }
3240
3341 /// Create a new TokioRuntime and bind it to the tokio runtime associated to this handle by default.
3442 pub fn tokio_with_handle ( handle : Handle ) -> Self {
3543 Self :: new ( Tokio :: default ( ) . with_handle ( handle) )
3644 }
45+
46+ /// Create a new TokioRuntime and bind it to this tokio runtime.
47+ pub fn tokio_with_runtime ( runtime : TokioRT ) -> Self {
48+ Self :: new ( Tokio :: default ( ) . with_runtime ( runtime) )
49+ }
3750}
3851
3952/// Dummy object implementing async common interfaces on top of tokio
40- #[ derive( Default , Debug , Clone ) ]
53+ #[ derive( Default , Debug ) ]
4154pub struct Tokio {
4255 handle : Option < Handle > ,
56+ runtime : Option < TokioRT > ,
4357}
4458
4559impl Tokio {
@@ -49,13 +63,32 @@ impl Tokio {
4963 self
5064 }
5165
66+ /// Bind to the tokio Runtime associated to this handle by default.
67+ pub fn with_runtime ( mut self , runtime : TokioRT ) -> Self {
68+ let handle = runtime. handle ( ) . clone ( ) ;
69+ self . runtime = Some ( runtime) ;
70+ self . with_handle ( handle)
71+ }
72+
5273 /// Bind to the current tokio Runtime by default.
5374 pub fn current ( ) -> Self {
5475 Self :: default ( ) . with_handle ( Handle :: current ( ) )
5576 }
5677
57- pub ( crate ) fn handle ( & self ) -> Option < Handle > {
58- Handle :: try_current ( ) . ok ( ) . or_else ( || self . handle . clone ( ) )
78+ fn handle ( & self ) -> Option < Handle > {
79+ self . runtime
80+ . as_ref ( )
81+ . map ( |r| r. handle ( ) . clone ( ) )
82+ . or_else ( || Handle :: try_current ( ) . ok ( ) )
83+ . or_else ( || self . handle . clone ( ) )
84+ }
85+
86+ fn enter ( & self ) -> Option < EnterGuard < ' _ > > {
87+ self . runtime
88+ . as_ref ( )
89+ . map ( TokioRT :: handle)
90+ . or ( self . handle . as_ref ( ) )
91+ . map ( Handle :: enter)
5992 }
6093}
6194
@@ -65,7 +98,9 @@ impl RuntimeKit for Tokio {}
6598
6699impl Executor for Tokio {
67100 fn block_on < T , F : Future < Output = T > > ( & self , f : F ) -> T {
68- if let Some ( handle) = self . handle ( ) {
101+ if let Some ( runtime) = self . runtime . as_ref ( ) {
102+ runtime. block_on ( f)
103+ } else if let Some ( handle) = self . handle ( ) {
69104 handle. block_on ( f)
70105 } else {
71106 Handle :: current ( ) . block_on ( f)
@@ -123,7 +158,7 @@ impl Reactor for Tokio {
123158 & self ,
124159 socket : H ,
125160 ) -> io:: Result < impl AsyncRead + AsyncWrite + Send + Unpin + ' static > {
126- let _enter = self . handle ( ) . as_ref ( ) . map ( |handle| handle . enter ( ) ) ;
161+ let _enter = self . enter ( ) ;
127162 cfg_if ! {
128163 if #[ cfg( unix) ] {
129164 Ok ( unix:: AsyncFdWrapper (
@@ -138,19 +173,20 @@ impl Reactor for Tokio {
138173 }
139174
140175 fn sleep ( & self , dur : Duration ) -> impl Future < Output = ( ) > + Send + ' static {
176+ let _enter = self . enter ( ) ;
141177 tokio:: time:: sleep ( dur)
142178 }
143179
144180 fn interval ( & self , dur : Duration ) -> impl Stream < Item = Instant > + Send + ' static {
145- let _enter = self . handle ( ) . as_ref ( ) . map ( |handle| handle . enter ( ) ) ;
181+ let _enter = self . enter ( ) ;
146182 IntervalStream :: new ( tokio:: time:: interval ( dur) ) . map ( tokio:: time:: Instant :: into_std)
147183 }
148184
149185 fn tcp_connect_addr (
150186 & self ,
151187 addr : SocketAddr ,
152188 ) -> impl Future < Output = io:: Result < Self :: TcpStream > > + Send + ' static {
153- let _enter = self . handle ( ) . as_ref ( ) . map ( |handle| handle . enter ( ) ) ;
189+ let _enter = self . enter ( ) ;
154190 async move { Ok ( TcpStream :: connect ( addr) . await ?. compat ( ) ) }
155191 }
156192}
0 commit comments