Skip to content

Fix compilation on wasm32 #54

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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