diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 4887225..b9c0517 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -2,5 +2,5 @@ # https://rust-lang.github.io/rustup-components-history [toolchain] channel = "nightly-2024-03-16" -components = ["rust-src", "rustfmt"] +components = ["rust-src", "rustfmt", "rust-analyzer"] targets = ["wasm32-unknown-unknown"] diff --git a/src/lib.rs b/src/lib.rs index a2685c4..7a6f222 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,4 @@ +#![feature(thread_id_value)] #![cfg_attr(target_arch = "wasm32", feature(stdarch_wasm_atomic_wait))] // Import reusable APIs from std diff --git a/src/wasm32/mod.rs b/src/wasm32/mod.rs index 8bcce7e..a186d54 100644 --- a/src/wasm32/mod.rs +++ b/src/wasm32/mod.rs @@ -13,7 +13,7 @@ use scoped::ScopeData; pub use scoped::{scope, Scope, ScopedJoinHandle}; use signal::Signal; use utils::SpinLockMutex; -pub use utils::{available_parallelism, get_wasm_bindgen_shim_script_path, get_worker_script, is_web_worker_thread}; +pub use utils::{available_parallelism, get_wasm_bindgen_shim_script_path, get_worker_script, is_main_thread}; use wasm_bindgen::prelude::*; use web_sys::{DedicatedWorkerGlobalScope, Worker, WorkerOptions, WorkerType}; @@ -57,8 +57,7 @@ impl WorkerMessage { pub fn post(self) { let req = Box::new(self); - js_sys::eval("self") - .unwrap() + js_sys::global() .dyn_into::() .unwrap() .post_message(&JsValue::from(Box::into_raw(req) as u32)) @@ -251,7 +250,7 @@ impl Builder { func: mem::transmute::, Box>(main), }; - if is_web_worker_thread() { + if !is_main_thread() { WorkerMessage::SpawnThread(BuilderRequest { builder: self, context }).post(); } else { self.spawn_for_context(context); diff --git a/src/wasm32/scoped.rs b/src/wasm32/scoped.rs index cd18532..df13c18 100644 --- a/src/wasm32/scoped.rs +++ b/src/wasm32/scoped.rs @@ -7,7 +7,7 @@ use std::{ }, }; -use super::{signal::Signal, utils::is_web_worker_thread, Builder, JoinInner}; +use super::{signal::Signal, utils::is_main_thread, Builder, JoinInner}; /// A scope to spawn scoped threads in. /// @@ -89,7 +89,7 @@ where F: for<'scope> FnOnce(&'scope Scope<'scope, 'env>) -> T, { // Fail early to avoid flaky panics that depend on execution time - if !is_web_worker_thread() { + if is_main_thread() { panic!("scope is not allowed on the main thread"); } diff --git a/src/wasm32/utils.rs b/src/wasm32/utils.rs index 1791657..ac94283 100644 --- a/src/wasm32/utils.rs +++ b/src/wasm32/utils.rs @@ -4,16 +4,15 @@ use std::{ sync::{LockResult, Mutex, MutexGuard, TryLockError}, }; +use js_sys::Reflect; use wasm_bindgen::prelude::*; -use web_sys::{Blob, Url, WorkerGlobalScope}; +use web_sys::{Blob, Url}; pub fn available_parallelism() -> io::Result { - if let Some(window) = web_sys::window() { - return Ok(NonZeroUsize::new(window.navigator().hardware_concurrency() as usize).unwrap()); - } - - if let Ok(worker) = js_sys::eval("self").unwrap().dyn_into::() { - return Ok(NonZeroUsize::new(worker.navigator().hardware_concurrency() as usize).unwrap()); + if let Ok(navigator) = Reflect::get(&js_sys::global(), &"navigator".into()) { + if let Ok(hardware_concurrency) = Reflect::get(&navigator, &"hardwareConcurrency".into()) { + return Ok(NonZeroUsize::new(hardware_concurrency.as_f64().unwrap() as usize).unwrap()); + } } Err(io::Error::new( @@ -22,8 +21,8 @@ pub fn available_parallelism() -> io::Result { )) } -pub fn is_web_worker_thread() -> bool { - js_sys::eval("self").unwrap().dyn_into::().is_ok() +pub fn is_main_thread() -> bool { + std::thread::current().id().as_u64().get() == 1_u64 } /// Extracts path of the `wasm_bindgen` generated .js shim script.