@@ -129,10 +129,12 @@ pub fn init_with_config(config: GlobalExecutorConfig) {
129
129
use future:: block_on;
130
130
loop {
131
131
let _ = std:: panic:: catch_unwind ( || {
132
- LOCAL_EXECUTOR . with ( |executor| {
133
- let local = executor. run ( future:: pending :: < ( ) > ( ) ) ;
134
- let global = GLOBAL_EXECUTOR . run ( future:: pending :: < ( ) > ( ) ) ;
135
- block_on ( future:: or ( local, global) )
132
+ enter02 ( || {
133
+ LOCAL_EXECUTOR . with ( |executor| {
134
+ let local = executor. run ( future:: pending :: < ( ) > ( ) ) ;
135
+ let global = GLOBAL_EXECUTOR . run ( future:: pending :: < ( ) > ( ) ) ;
136
+ block_on ( future:: or ( local, global) )
137
+ } )
136
138
} )
137
139
} ) ;
138
140
}
@@ -174,7 +176,7 @@ pub fn block_on<F: Future<Output = T>, T>(future: F) -> T {
174
176
use async_io:: block_on;
175
177
#[ cfg( not( feature = "async-io" ) ) ]
176
178
use future:: block_on;
177
- LOCAL_EXECUTOR . with ( |executor| block_on ( executor. run ( future) ) )
179
+ enter02 ( || LOCAL_EXECUTOR . with ( |executor| block_on ( executor. run ( future) ) ) )
178
180
}
179
181
180
182
/// Spawns a task onto the multi-threaded global executor.
@@ -226,3 +228,36 @@ pub fn spawn<F: Future<Output = T> + Send + 'static, T: Send + 'static>(future:
226
228
pub fn spawn_local < F : Future < Output = T > + ' static , T : ' static > ( future : F ) -> Task < T > {
227
229
LOCAL_EXECUTOR . with ( |executor| executor. spawn ( future) )
228
230
}
231
+
232
+ /// Enters the tokio context if the `tokio02` feature is enabled.
233
+ fn enter02 < T > ( f : impl FnOnce ( ) -> T ) -> T {
234
+ #[ cfg( not( feature = "tokio02" ) ) ]
235
+ return f ( ) ;
236
+
237
+ #[ cfg( feature = "tokio02" ) ]
238
+ {
239
+ use std:: cell:: Cell ;
240
+ use tokio:: runtime:: Runtime ;
241
+
242
+ thread_local ! {
243
+ /// The level of nested `enter` calls we are in, to ensure that the outermost always
244
+ /// has a runtime spawned.
245
+ static NESTING : Cell <usize > = Cell :: new( 0 ) ;
246
+ }
247
+
248
+ /// The global tokio runtime.
249
+ static RT : Lazy < Runtime > = new ( || Runtime :: new ( ) . expect ( "cannot initialize tokio" ) ) ;
250
+
251
+ NESTING . with ( |nesting| {
252
+ let res = if nesting. get ( ) == 0 {
253
+ nesting. replace ( 1 ) ;
254
+ RT . enter ( f)
255
+ } else {
256
+ nesting. replace ( nesting. get ( ) + 1 ) ;
257
+ f ( )
258
+ } ;
259
+ nesting. replace ( nesting. get ( ) - 1 ) ;
260
+ res
261
+ } )
262
+ }
263
+ }
0 commit comments