@@ -18,8 +18,8 @@ use serde_json;
1818// Global runtime - one runtime per process that stays alive
1919static GLOBAL_RUNTIME : OnceLock < tokio:: runtime:: Runtime > = OnceLock :: new ( ) ;
2020
21- // Global runtime enter guard - keeps runtime as current for the entire process (Windows fix)
22- static GLOBAL_RUNTIME_GUARD : OnceLock < Mutex < Option < tokio :: runtime :: EnterGuard < ' static > > > > = OnceLock :: new ( ) ;
21+ // Flag to track if runtime has been entered (Windows fix for nested spawns )
22+ static RUNTIME_ENTERED : OnceLock < ( ) > = OnceLock :: new ( ) ;
2323
2424// Global client instance - one client per process
2525static GLOBAL_CLIENT : OnceLock < Mutex < Option < McpClient > > > = OnceLock :: new ( ) ;
@@ -253,15 +253,17 @@ fn get_runtime() -> &'static tokio::runtime::Runtime {
253253 tokio:: runtime:: Runtime :: new ( ) . expect ( "Failed to create Tokio runtime" )
254254 } ) ;
255255
256- // On first call, enter the runtime and keep the guard alive forever (Windows fix for nested spawns)
257- GLOBAL_RUNTIME_GUARD . get_or_init ( || {
256+ // On first call, enter the runtime and forget the guard (Windows fix for nested spawns)
257+ // This makes the runtime "current" for the entire program duration
258+ RUNTIME_ENTERED . get_or_init ( || {
258259 // SAFETY: The runtime is stored in a static and lives for the entire program duration
259260 let guard = unsafe {
260261 let runtime_ptr: * const tokio:: runtime:: Runtime = runtime;
261262 let runtime_ref: & ' static tokio:: runtime:: Runtime = & * runtime_ptr;
262263 runtime_ref. enter ( )
263264 } ;
264- Mutex :: new ( Some ( guard) )
265+ // Forget the guard so it never gets dropped - keeps runtime as current forever
266+ std:: mem:: forget ( guard) ;
265267 } ) ;
266268
267269 runtime
0 commit comments