jive/src/lib.rs

81 lines
1.9 KiB
Rust

#![feature(once_cell)]
use jitterbug::Executor;
use std::{
future::{pending, Future},
lazy::SyncOnceCell,
};
pub use foxtrot::{io, net, time};
pub mod sync {
pub use jitterbug::{oneshot, Dropped as OneshotError, Receiver, Sender};
}
pub mod task {
pub use jitterbug::{JoinError, JoinHandle};
use std::future::Future;
pub fn spawn<T: Send + 'static>(
future: impl Future<Output = T> + Send + 'static,
) -> JoinHandle<T> {
super::Runtime::get_or_init().executor.spawn(future)
}
pub fn spawn_blocking<T: Send + 'static>(
callback: impl FnOnce() -> T + Send + 'static,
) -> JoinHandle<T> {
super::Runtime::get_or_init()
.blocking
.spawn(async move { (callback)() })
}
}
pub use task::{spawn, spawn_blocking};
pub fn block_on<T: Send + 'static>(
future: impl Future<Output = T> + Send + 'static,
) -> Result<T, jitterbug::JoinError> {
foxtrot::block_on(Runtime::get_or_init().executor.run_with(future)).unwrap()
}
static RUNTIME: SyncOnceCell<Runtime> = SyncOnceCell::new();
struct Runtime {
executor: Executor,
blocking: Executor,
}
impl Runtime {
fn get_or_init() -> &'static Self {
RUNTIME.get_or_init(Self::new)
}
fn new() -> Self {
let executor = Executor::new();
let blocking = Executor::new();
let base_threads = std::thread::available_parallelism()
.map(usize::from)
.unwrap_or(1);
let blocking_threads = base_threads * 5;
for _ in 0..base_threads {
let executor = executor.clone();
std::thread::spawn(move || {
let _ = foxtrot::block_on(executor.into_runner());
});
}
for _ in 0..blocking_threads {
let blocking = blocking.clone();
std::thread::spawn(move || blocking.block_on(pending::<()>()));
}
Runtime { executor, blocking }
}
}