#![doc = include_str!("../README.md")]
#[cfg(all(target_arch = "wasm32", not(doc), not(target_feature = "atomics")))]
compile_error!("Did you forget to enable `atomics` and `bulk-memory` features as outlined in wasm-bindgen-rayon README?");
use crossbeam_channel::{bounded, Receiver, Sender};
use js_sys::Promise;
use rayon::{ThreadBuilder, ThreadPoolBuilder};
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsValue;
#[cfg(feature = "no-bundler")]
use js_sys::JsString;
#[allow(non_camel_case_types)]
#[wasm_bindgen]
#[doc(hidden)]
pub struct wbg_rayon_PoolBuilder {
num_threads: usize,
sender: Sender<ThreadBuilder>,
receiver: Receiver<ThreadBuilder>,
}
#[cfg_attr(
not(feature = "no-bundler"),
wasm_bindgen(module = "/src/workerHelpers.js")
)]
#[cfg_attr(
feature = "no-bundler",
wasm_bindgen(module = "/src/workerHelpers.no-bundler.js")
)]
extern "C" {
#[wasm_bindgen(js_name = startWorkers)]
fn start_workers(module: JsValue, memory: JsValue, builder: wbg_rayon_PoolBuilder) -> Promise;
}
#[wasm_bindgen]
impl wbg_rayon_PoolBuilder {
fn new(num_threads: usize) -> Self {
let (sender, receiver) = bounded(num_threads);
Self {
num_threads,
sender,
receiver,
}
}
#[cfg(feature = "no-bundler")]
#[wasm_bindgen(js_name = mainJS)]
pub fn main_js(&self) -> JsString {
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(thread_local_v2, js_namespace = ["import", "meta"], js_name = url)]
static URL: JsString;
}
URL.with(Clone::clone)
}
#[wasm_bindgen(js_name = numThreads)]
pub fn num_threads(&self) -> usize {
self.num_threads
}
pub fn receiver(&self) -> *const Receiver<ThreadBuilder> {
&self.receiver
}
pub fn build(&mut self) {
ThreadPoolBuilder::new()
.num_threads(self.num_threads)
.spawn_handler(move |thread| {
self.sender.send(thread).unwrap_throw();
Ok(())
})
.build_global()
.unwrap_throw();
}
}
#[wasm_bindgen(js_name = initThreadPool)]
#[doc(hidden)]
pub fn init_thread_pool(num_threads: usize) -> Promise {
start_workers(
wasm_bindgen::module(),
wasm_bindgen::memory(),
wbg_rayon_PoolBuilder::new(num_threads),
)
}
#[wasm_bindgen]
#[allow(clippy::not_unsafe_ptr_arg_deref)]
#[doc(hidden)]
pub fn wbg_rayon_start_worker(receiver: *const Receiver<ThreadBuilder>)
where
Receiver<ThreadBuilder>: Sync,
{
let receiver = unsafe { &*receiver };
receiver.recv().unwrap_throw().run()
}