forge_core_utils/
tokio.rs1use std::{future::Future, sync::OnceLock};
2
3use tokio::runtime::{Builder, Handle, Runtime, RuntimeFlavor};
4
5fn rt() -> &'static Runtime {
6 static RT: OnceLock<Runtime> = OnceLock::new();
7 RT.get_or_init(|| {
8 Builder::new_multi_thread()
9 .enable_all()
10 .build()
11 .expect("failed to build global Tokio runtime")
12 })
13}
14
15pub fn block_on<F, T>(fut: F) -> T
18where
19 F: Future<Output = T> + Send,
20 T: Send,
21{
22 match Handle::try_current() {
23 Ok(h) => match h.runtime_flavor() {
25 RuntimeFlavor::MultiThread => tokio::task::block_in_place(|| rt().block_on(fut)),
27 RuntimeFlavor::CurrentThread | _ => std::thread::scope(|s| {
29 s.spawn(|| rt().block_on(fut))
30 .join()
31 .expect("thread panicked")
32 }),
33 },
34 Err(_) => rt().block_on(fut),
36 }
37}