diff --git a/Cargo.toml b/Cargo.toml index f478bdc..8c3cda6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,11 +17,11 @@ async-channel = "1.4.2" async-executor = "1.1.0" async-fs = "1.3.0" async-io = "1.1.2" -async-lock = "2.1.3" +async-lock = "2.3.0" async-net = "1.4.3" async-process = "1.0.0" blocking = "1.0.0" -futures-lite = "1.7.0" +futures-lite = "1.11.0" once_cell = "1.4.1" [dev-dependencies] diff --git a/src/lib.rs b/src/lib.rs index 8c903ea..4f7c7e9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -37,19 +37,12 @@ #[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}, + futures_lite::{future, io, pin, prelude, ready, stream}, }; #[doc(inline)] @@ -58,71 +51,5 @@ pub use { async_process as process, }; -pub mod prelude { - //! Traits [`Future`], [`Stream`], [`AsyncRead`], [`AsyncWrite`], [`AsyncBufRead`], - //! [`AsyncSeek`], and their extensions. - //! - //! # Examples - //! - //! ``` - //! use smol::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}, - }; -} - -/// Spawns a task onto the global executor (single-threaded by default). -/// -/// There is a global executor that gets lazily initialized on first use. It is included in this -/// library for convenience when writing unit tests and small programs, but it is otherwise -/// more advisable to create your own [`Executor`]. -/// -/// By default, the global executor is run by a single background thread, but you can also -/// configure the number of threads by setting the `SMOL_THREADS` environment variable. -/// -/// # Examples -/// -/// ``` -/// let task = smol::spawn(async { -/// 1 + 2 -/// }); -/// -/// smol::block_on(async { -/// assert_eq!(task.await, 3); -/// }); -/// ``` -pub fn spawn(future: impl Future + Send + 'static) -> Task { - static GLOBAL: Lazy> = Lazy::new(|| { - let num_threads = { - // Parse SMOL_THREADS or default to 1. - 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 { - catch_unwind(|| async_io::block_on(GLOBAL.run(future::pending::<()>()))) - .ok(); - } - }) - .expect("cannot spawn executor thread"); - } - - Executor::new() - }); - - GLOBAL.spawn(future) -} +mod spawn; +pub use spawn::spawn; diff --git a/src/spawn.rs b/src/spawn.rs new file mode 100644 index 0000000..8ce491a --- /dev/null +++ b/src/spawn.rs @@ -0,0 +1,55 @@ +use std::future::Future; +use std::panic::catch_unwind; +use std::thread; + +use async_executor::{Executor, Task}; +use async_io::block_on; +use futures_lite::future; +use once_cell::sync::Lazy; + +/// Spawns a task onto the global executor (single-threaded by default). +/// +/// There is a global executor that gets lazily initialized on first use. It is included in this +/// library for convenience when writing unit tests and small programs, but it is otherwise +/// more advisable to create your own [`Executor`]. +/// +/// By default, the global executor is run by a single background thread, but you can also +/// configure the number of threads by setting the `SMOL_THREADS` environment variable. +/// +/// # Examples +/// +/// ``` +/// let task = smol::spawn(async { +/// 1 + 2 +/// }); +/// +/// smol::block_on(async { +/// assert_eq!(task.await, 3); +/// }); +/// ``` +pub fn spawn(future: impl Future + Send + 'static) -> Task { + static GLOBAL: Lazy> = Lazy::new(|| { + let num_threads = { + // Parse SMOL_THREADS or default to 1. + 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 { + catch_unwind(|| block_on(GLOBAL.run(future::pending::<()>()))).ok(); + } + }) + .expect("cannot spawn executor thread"); + } + + Executor::new() + }); + + GLOBAL.spawn(future) +}