diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 04b210a..fd541ee 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,11 +37,14 @@ jobs: - uses: actions/checkout@v4 - name: Install Rust run: rustup update ${{ matrix.rust }} && rustup default ${{ matrix.rust }} + - run: rustup target add wasm32-unknown-unknown - run: cargo build --all --all-features --all-targets - name: Run cargo check (without dev-dependencies to catch missing feature flags) if: startsWith(matrix.rust, 'nightly') run: cargo check -Z features=dev_dep - run: cargo test + - name: Run cargo check for WASM + run: cargo check --all --all-features --all-targets --target wasm32-unknown-unknown msrv: runs-on: ubuntu-latest diff --git a/Cargo.toml b/Cargo.toml index 3b6f22b..d158271 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,6 @@ exclude = ["/.*"] [dependencies] async-channel = "2.0.0" -async-lock = "3.0.0" async-task = "4.0.2" fastrand = "2.0.0" futures-io = { version = "0.3.28", default-features = false, features = ["std"] } @@ -24,5 +23,8 @@ futures-lite = { version = "2.0.0", default-features = false } piper = "0.2.0" tracing = { version = "0.1.37", default-features = false } +[target.'cfg(not(target_family = "wasm"))'.dependencies] +async-lock = "3.0.0" + [dev-dependencies] futures-lite = "2.0.0" diff --git a/src/lib.rs b/src/lib.rs index 17df717..8f45643 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -86,7 +86,6 @@ use std::any::Any; use std::collections::VecDeque; -use std::env; use std::fmt; use std::io::{self, Read, Seek, SeekFrom, Write}; use std::num::NonZeroUsize; @@ -98,8 +97,10 @@ use std::task::{Context, Poll}; use std::thread; use std::time::Duration; +#[cfg(not(target_family = "wasm"))] +use std::env; + use async_channel::{bounded, Receiver}; -use async_lock::OnceCell; use async_task::Runnable; use futures_io::{AsyncRead, AsyncSeek, AsyncWrite}; use futures_lite::{future, prelude::*, ready}; @@ -109,15 +110,19 @@ use piper::{pipe, Reader, Writer}; pub use async_task::Task; /// Default value for max threads that Executor can grow to +#[cfg(not(target_family = "wasm"))] const DEFAULT_MAX_THREADS: usize = 500; /// Minimum value for max threads config +#[cfg(not(target_family = "wasm"))] const MIN_MAX_THREADS: usize = 1; /// Maximum value for max threads config +#[cfg(not(target_family = "wasm"))] const MAX_MAX_THREADS: usize = 10000; /// Env variable that allows to override default value for max threads. +#[cfg(not(target_family = "wasm"))] const MAX_THREADS_ENV: &str = "BLOCKING_MAX_THREADS"; /// The blocking executor. @@ -149,6 +154,7 @@ struct Inner { } impl Executor { + #[cfg(not(target_family = "wasm"))] fn max_threads() -> usize { match env::var(MAX_THREADS_ENV) { Ok(v) => v @@ -159,15 +165,16 @@ impl Executor { } } - /// Spawns a future onto this executor. - /// - /// Returns a [`Task`] handle for the spawned task. - fn spawn(future: impl Future + Send + 'static) -> Task { - static EXECUTOR: OnceCell = OnceCell::new(); + /// Get a reference to the global executor. + #[inline] + fn get() -> &'static Self { + #[cfg(not(target_family = "wasm"))] + { + use async_lock::OnceCell; - let (runnable, task) = async_task::spawn(future, |r| { - // Initialize the executor if we haven't already. - let executor = EXECUTOR.get_or_init_blocking(|| { + static EXECUTOR: OnceCell = OnceCell::new(); + + return EXECUTOR.get_or_init_blocking(|| { let thread_limit = Self::max_threads(); Executor { inner: Mutex::new(Inner { @@ -179,6 +186,19 @@ impl Executor { cvar: Condvar::new(), } }); + } + + #[cfg(target_family = "wasm")] + panic!("cannot spawn a blocking task on WASM") + } + + /// Spawns a future onto this executor. + /// + /// Returns a [`Task`] handle for the spawned task. + fn spawn(future: impl Future + Send + 'static) -> Task { + let (runnable, task) = async_task::spawn(future, |r| { + // Initialize the executor if we haven't already. + let executor = Self::get(); // Schedule the task on our executor. executor.schedule(r) @@ -943,9 +963,10 @@ impl AsyncSeek for Unblock { } } -#[cfg(test)] +#[cfg(all(test, not(target_family = "wasm")))] mod tests { use super::*; + #[test] fn test_max_threads() { // properly set env var