Skip to content

Commit

Permalink
Fix thread parking on WebAssembly
Browse files Browse the repository at this point in the history
On WebAssembly the notification state was not checked
before sleeping and thus wrongfully ignored.

Additionally this refines the check whether threads are
available on a particular WebAssembly target.
  • Loading branch information
surban committed Dec 18, 2024
1 parent b54b9d4 commit f2b6449
Showing 1 changed file with 8 additions and 5 deletions.
13 changes: 8 additions & 5 deletions tokio/src/runtime/park.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,7 @@ impl ParkThread {
pub(crate) fn park_timeout(&mut self, duration: Duration) {
#[cfg(loom)]
CURRENT_THREAD_PARK_COUNT.with(|count| count.fetch_add(1, SeqCst));

// Wasm doesn't have threads, so just sleep.
#[cfg(not(target_family = "wasm"))]
self.inner.park_timeout(duration);
#[cfg(target_family = "wasm")]
std::thread::sleep(duration);
}

pub(crate) fn shutdown(&mut self) {
Expand Down Expand Up @@ -158,12 +153,20 @@ impl Inner {
Err(actual) => panic!("inconsistent park_timeout state; actual = {actual}"),
}

#[cfg(not(all(target_family = "wasm", not(target_feature = "atomics"))))]
// Wait with a timeout, and if we spuriously wake up or otherwise wake up
// from a notification, we just want to unconditionally set the state back to
// empty, either consuming a notification or un-flagging ourselves as
// parked.
let (_m, _result) = self.condvar.wait_timeout(m, dur).unwrap();

#[cfg(all(target_family = "wasm", not(target_feature = "atomics")))]
// Wasm without atomics doesn't have threads, so just sleep.
{
let _m = m;
std::thread::sleep(dur);
}

match self.state.swap(EMPTY, SeqCst) {
NOTIFIED => {} // got a notification, hurray!
PARKED => {} // no notification, alas
Expand Down

0 comments on commit f2b6449

Please sign in to comment.