use std::{future::Future, sync::OnceLock};
use tokio::runtime::{Builder, Handle, Runtime, RuntimeFlavor};
fn rt() -> &'static Runtime {
static RT: OnceLock<Runtime> = OnceLock::new();
RT.get_or_init(|| {
Builder::new_multi_thread()
.enable_all()
.build()
.expect("failed to build global Tokio runtime")
})
}
pub fn block_on<F, T>(fut: F) -> T
where
F: Future<Output = T> + Send,
T: Send,
{
match Handle::try_current() {
Ok(h) => match h.runtime_flavor() {
RuntimeFlavor::MultiThread => tokio::task::block_in_place(|| rt().block_on(fut)),
RuntimeFlavor::CurrentThread | _ => std::thread::scope(|s| {
s.spawn(|| rt().block_on(fut))
.join()
.expect("thread panicked")
}),
},
Err(_) => rt().block_on(fut),
}
}