use std::sync::LazyLock;
use tokio::runtime::{Builder, Runtime};
use crate::co::Handle;
#[cfg(not(feature = "coroutine-heavy"))]
static RUNTIME: LazyLock<Runtime> = LazyLock::new(|| {
Builder::new_current_thread()
.enable_all()
.build()
.expect("cannot create current-thread tokio runtime")
});
static BACKGROUND_RUNTIME: LazyLock<Runtime> = LazyLock::new(|| {
#[cfg(feature = "coroutine-heavy")]
{
Builder::new_multi_thread()
.enable_all()
.build()
.expect("cannot create heavy background tokio runtime")
}
#[cfg(not(feature = "coroutine-heavy"))]
{
Builder::new_multi_thread()
.worker_threads(1)
.enable_all()
.build()
.expect("cannot create background tokio runtime")
}
});
pub(crate) fn foreground() -> &'static Runtime {
#[cfg(not(feature = "coroutine-heavy"))]
{
&RUNTIME
}
#[cfg(feature = "coroutine-heavy")]
{
&BACKGROUND_RUNTIME
}
}
pub(crate) fn background() -> &'static Runtime {
&BACKGROUND_RUNTIME
}
#[inline(always)]
#[cfg(not(feature = "coroutine-heavy"))]
pub fn block<F>(future: F) -> F::Output
where
F: Future,
{
RUNTIME.block_on(future)
}
#[inline(always)]
pub fn spawn<F>(future: F) -> Handle<F::Output>
where
F: Future + Send + 'static,
F::Output: Send + 'static,
{
Handle(BACKGROUND_RUNTIME.spawn(future))
}
#[inline(always)]
#[cfg(feature = "coroutine-heavy")]
pub fn spawn_blocking<F, R>(func: F) -> Handle<F::Output>
where
F: FnOnce() -> R + Send + 'static,
R: Send + 'static,
{
Handle(BACKGROUND_RUNTIME.spawn_blocking(func))
}
#[inline(always)]
pub fn run<F>(future: F) -> F::Output
where
F: Future,
{
BACKGROUND_RUNTIME.block_on(future)
}