81 lines
1.9 KiB
Rust
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 }
|
|
}
|
|
}
|