#![forbid(unsafe_code)]
#![warn(missing_docs, missing_debug_implementations, rust_2018_idioms)]
#[cfg(doctest)]
doc_comment::doctest!("../README.md");
use std::future::Future;
use std::panic::catch_unwind;
use std::thread;
use once_cell::sync::Lazy;
#[doc(inline)]
pub use {
async_executor::{Executor, LocalExecutor, Task},
async_io::{block_on, Async, Timer},
blocking::{unblock, Unblock},
futures_lite::{future, io, stream},
futures_lite::{pin, ready},
};
#[doc(inline)]
pub use {
async_channel as channel, async_fs as fs, async_lock as lock, async_net as net,
async_process as process,
};
pub mod prelude {
#[doc(no_inline)]
pub use futures_lite::{
future::{Future, FutureExt},
io::{AsyncBufRead, AsyncBufReadExt},
io::{AsyncRead, AsyncReadExt},
io::{AsyncSeek, AsyncSeekExt},
io::{AsyncWrite, AsyncWriteExt},
stream::{Stream, StreamExt},
};
}
pub fn spawn<T: Send + 'static>(future: impl Future<Output = T> + Send + 'static) -> Task<T> {
static GLOBAL: Lazy<Executor> = Lazy::new(|| {
let num_threads = {
std::env::var("SMOL_THREADS")
.ok()
.and_then(|s| s.parse().ok())
.unwrap_or(1)
};
for n in 1..=num_threads {
thread::Builder::new()
.name(format!("smol-{}", n))
.spawn(|| {
loop {
let _ = catch_unwind(|| {
async_io::block_on(GLOBAL.run(future::pending::<()>()))
});
}
})
.expect("cannot spawn executor thread");
}
Executor::new()
});
GLOBAL.spawn(future)
}