use std::sync::OnceLock;
pub use std::time::Duration;
use wasm_bindgen::JsCast;
use wasm_safe_thread::Builder as WasmThreadBuilder;
pub use crate::common::thread_id::active_named_thread_count;
use crate::common::thread_id::{counted, thread_id_hash};
fn wasm_shim_name() -> &'static OnceLock<String> {
static CELL: OnceLock<String> = OnceLock::new();
&CELL
}
pub fn set_wasm_shim_name(name: impl Into<String>) {
let _ = wasm_shim_name().set(name.into());
}
pub fn keep_worker_alive() {
wasm_safe_thread::task_begin();
}
pub type Thread = wasm_safe_thread::Thread;
pub type ThreadId = wasm_safe_thread::ThreadId;
#[inline]
pub fn yield_now() {}
#[inline]
#[must_use]
pub fn is_worker_thread() -> bool {
js_sys::global()
.dyn_into::<web_sys::DedicatedWorkerGlobalScope>()
.is_ok()
}
#[inline]
#[must_use]
pub fn is_main_thread() -> bool {
!is_worker_thread()
}
#[inline]
pub fn assert_main_thread(_label: &str) {
if !is_main_thread() {
panic!("main-thread-only call executed on worker thread: {_label}");
}
}
#[inline]
pub fn assert_not_main_thread(_label: &str) {
if is_main_thread() {
panic!("worker-thread-only call executed on main thread: {_label}");
}
}
pub type JoinHandle<T> = wasm_safe_thread::JoinHandle<T>;
#[inline]
#[must_use]
pub fn current() -> Thread {
wasm_safe_thread::current()
}
pub fn spawn_named<F, T, N: Into<String>>(name: N, f: F) -> JoinHandle<T>
where
F: FnOnce() -> T + Send + 'static,
T: Send + 'static,
{
let _name = name.into();
spawn(counted(f))
}
pub fn spawn<F, T>(f: F) -> JoinHandle<T>
where
F: FnOnce() -> T + Send + 'static,
T: Send + 'static,
{
let mut builder = WasmThreadBuilder::new();
if let Some(shim) = wasm_shim_name().get() {
builder = builder.shim_name(shim.clone());
}
builder
.spawn(move || {
console_error_panic_hook::set_once();
f()
})
.expect("BUG: WASM Worker spawn must succeed; only fails on OS resource exhaustion")
}
#[inline]
pub fn sleep(duration: Duration) {
wasm_safe_thread::sleep(duration);
}
#[inline]
pub fn paced_backoff(duration: Duration) {
sleep(duration);
}
#[inline]
pub fn park() {
wasm_safe_thread::park();
}
#[inline]
pub fn park_timeout(duration: Duration) {
wasm_safe_thread::park_timeout(duration);
}
#[inline]
pub fn unpark(t: &Thread) {
t.unpark();
}
#[inline]
#[must_use]
pub fn current_thread_id() -> u64 {
thread_id_hash(current().id())
}
#[inline]
#[must_use]
pub fn available_parallelism() -> Option<std::num::NonZeroUsize> {
wasm_safe_thread::available_parallelism().ok()
}