Skip to content

Commit

Permalink
bugfix: Fix compilation on wasm32
Browse files Browse the repository at this point in the history
Signed-off-by: John Nunley <dev@notgull.net>
  • Loading branch information
notgull authored Nov 13, 2023
1 parent 81ec3dd commit 9676493
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 12 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@ 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"] }
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"
43 changes: 32 additions & 11 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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};
Expand All @@ -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.
Expand Down Expand Up @@ -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
Expand All @@ -159,15 +165,16 @@ impl Executor {
}
}

/// Spawns a future onto this executor.
///
/// Returns a [`Task`] handle for the spawned task.
fn spawn<T: Send + 'static>(future: impl Future<Output = T> + Send + 'static) -> Task<T> {
static EXECUTOR: OnceCell<Executor> = 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<Executor> = OnceCell::new();

return EXECUTOR.get_or_init_blocking(|| {
let thread_limit = Self::max_threads();
Executor {
inner: Mutex::new(Inner {
Expand All @@ -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<T: Send + 'static>(future: impl Future<Output = T> + Send + 'static) -> Task<T> {
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)
Expand Down Expand Up @@ -943,9 +963,10 @@ impl<T: Seek + Send + 'static> AsyncSeek for Unblock<T> {
}
}

#[cfg(test)]
#[cfg(all(test, not(target_family = "wasm")))]
mod tests {
use super::*;

#[test]
fn test_max_threads() {
// properly set env var
Expand Down

0 comments on commit 9676493

Please sign in to comment.