Skip to content

Commit

Permalink
Use plain spinlock without thread::sleep on wasm32
Browse files Browse the repository at this point in the history
Using a mutex on the main thread in web builds isn't allowed, and
neither is using `thread::sleep` on the main thread in web builds. Only
a plain spinlock will work.
  • Loading branch information
white-axe committed Nov 29, 2023
1 parent fcf3849 commit d323799
Showing 1 changed file with 17 additions and 10 deletions.
27 changes: 17 additions & 10 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ use std::{
fmt,
};

#[cfg(feature = "spin")]
#[cfg(any(feature = "spin", target_arch = "wasm32"))]
use spin1::{Mutex as Spinlock, MutexGuard as SpinlockGuard};
use crate::signal::{Signal, SyncSignal};

Expand Down Expand Up @@ -257,13 +257,13 @@ enum TryRecvTimeoutError {
}

// TODO: Investigate some sort of invalidation flag for timeouts
#[cfg(feature = "spin")]
#[cfg(any(feature = "spin", target_arch = "wasm32"))]
struct Hook<T, S: ?Sized>(Option<Spinlock<Option<T>>>, S);

#[cfg(not(feature = "spin"))]
#[cfg(not(any(feature = "spin", target_arch = "wasm32")))]
struct Hook<T, S: ?Sized>(Option<Mutex<Option<T>>>, S);

#[cfg(feature = "spin")]
#[cfg(any(feature = "spin", target_arch = "wasm32"))]
impl<T, S: ?Sized + Signal> Hook<T, S> {
pub fn slot(msg: Option<T>, signal: S) -> Arc<Self>
where
Expand All @@ -277,7 +277,7 @@ impl<T, S: ?Sized + Signal> Hook<T, S> {
}
}

#[cfg(not(feature = "spin"))]
#[cfg(not(any(feature = "spin", target_arch = "wasm32")))]
impl<T, S: ?Sized + Signal> Hook<T, S> {
pub fn slot(msg: Option<T>, signal: S) -> Arc<Self>
where
Expand Down Expand Up @@ -392,7 +392,14 @@ impl<T> Hook<T, SyncSignal> {
}
}

#[cfg(feature = "spin")]
#[cfg(target_arch = "wasm32")]
#[inline]
fn wait_lock<T>(lock: &Spinlock<T>) -> SpinlockGuard<T> {
// `thread::sleep` is not allowed in the main thread in web builds
lock.lock()
}

#[cfg(all(feature = "spin", not(target_arch = "wasm32")))]
#[inline]
fn wait_lock<T>(lock: &Spinlock<T>) -> SpinlockGuard<T> {
let mut i = 4;
Expand All @@ -409,18 +416,18 @@ fn wait_lock<T>(lock: &Spinlock<T>) -> SpinlockGuard<T> {
}
}

#[cfg(not(feature = "spin"))]
#[cfg(not(any(feature = "spin", target_arch = "wasm32")))]
#[inline]
fn wait_lock<'a, T>(lock: &'a Mutex<T>) -> MutexGuard<'a, T> {
lock.lock().unwrap()
}

#[cfg(not(feature = "spin"))]
#[cfg(not(any(feature = "spin", target_arch = "wasm32")))]
use std::sync::{Mutex, MutexGuard};

#[cfg(feature = "spin")]
#[cfg(any(feature = "spin", target_arch = "wasm32"))]
type ChanLock<T> = Spinlock<T>;
#[cfg(not(feature = "spin"))]
#[cfg(not(any(feature = "spin", target_arch = "wasm32")))]
type ChanLock<T> = Mutex<T>;


Expand Down

0 comments on commit d323799

Please sign in to comment.