Skip to content

Commit

Permalink
runtime: fix thread parking on WebAssembly (#7041)
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 authored Jan 6, 2025
1 parent acd6627 commit a1520f5
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 a1520f5

Please sign in to comment.