Skip to content

Commit 8dd20c9

Browse files
committed
fix(lib): update runtime handling to spawn background thread for persistent Tokio runtime
1 parent c12fd57 commit 8dd20c9

File tree

1 file changed

+12
-8
lines changed

1 file changed

+12
-8
lines changed

src/lib.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -247,23 +247,27 @@ pub struct McpClient {
247247
server_url: Mutex<Option<String>>,
248248
}
249249

250-
/// Get or create the global Tokio runtime and ensure it's entered
250+
/// Get or create the global Tokio runtime and ensure it's running
251251
fn get_runtime() -> &'static tokio::runtime::Runtime {
252252
let runtime = GLOBAL_RUNTIME.get_or_init(|| {
253253
tokio::runtime::Runtime::new().expect("Failed to create Tokio runtime")
254254
});
255255

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
256+
// On first call, spawn a background thread to keep the runtime active forever (Windows fix)
258257
RUNTIME_ENTERED.get_or_init(|| {
259258
// SAFETY: The runtime is stored in a static and lives for the entire program duration
260-
let guard = unsafe {
259+
unsafe {
261260
let runtime_ptr: *const tokio::runtime::Runtime = runtime;
262261
let runtime_ref: &'static tokio::runtime::Runtime = &*runtime_ptr;
263-
runtime_ref.enter()
264-
};
265-
// Forget the guard so it never gets dropped - keeps runtime as current forever
266-
std::mem::forget(guard);
262+
263+
// Spawn a background thread that keeps the runtime active
264+
std::thread::spawn(move || {
265+
runtime_ref.block_on(async {
266+
// Keep this future running forever to maintain runtime context
267+
std::future::pending::<()>().await
268+
});
269+
});
270+
}
267271
});
268272

269273
runtime

0 commit comments

Comments
 (0)