diff --git a/src/lib.rs b/src/lib.rs index 6f33d6a..a605b13 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -79,9 +79,11 @@ pub mod prelude { /// Spawns a task onto the single-threaded global executor. /// -/// There is a single-threaded global executor that gets lazily initialized on first use. It is -/// advisable to use it in tests or small programs, but it is otherwise a better idea to define +/// There is a (single-threaded by default) global executor that gets lazily initialized on first use. +/// It is advisable to use it in tests or small programs, but it is otherwise a better idea to define /// your own [`Executor`]s. +/// You can configure the number of threads of the global executor using the `SMOL_THREADS` environment +/// variable. /// /// # Examples /// @@ -96,15 +98,22 @@ pub mod prelude { /// ``` pub fn spawn(future: impl Future + Send + 'static) -> Task { static GLOBAL: Lazy = Lazy::new(|| { - thread::Builder::new() - .name("smol".to_string()) - .spawn(|| { - loop { + let num_threads = { + // Parse SMOL_THREADS or run a monothreaded executor. + 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::<()>()))); - } - }) - .unwrap(); + }) + .expect("cannot spawn executor thread"); + } Executor::new() }); GLOBAL.spawn(future)