@@ -129,10 +129,12 @@ pub fn init_with_config(config: GlobalExecutorConfig) {
129129 use future:: block_on;
130130 loop {
131131 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+ } )
136138 } )
137139 } ) ;
138140 }
@@ -174,7 +176,7 @@ pub fn block_on<F: Future<Output = T>, T>(future: F) -> T {
174176 use async_io:: block_on;
175177 #[ cfg( not( feature = "async-io" ) ) ]
176178 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) ) ) )
178180}
179181
180182/// 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:
226228pub fn spawn_local < F : Future < Output = T > + ' static , T : ' static > ( future : F ) -> Task < T > {
227229 LOCAL_EXECUTOR . with ( |executor| executor. spawn ( future) )
228230}
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