#![cfg_attr(
feature = "nightly",
feature(external_doc),
doc(include = "../README.md")
)]
#![cfg_attr(
not(feature = "nightly"),
doc = "Check out documentation in [README.md](https://github.com/GoogleChromeLabs/wasm-bindgen-rayon)."
)]
#[cfg(not(target_feature = "atomics"))]
compile_error!("Did you forget to enable `atomics` and `bulk-memory` features as outlined in wasm-bindgen-rayon README?");
use js_sys::Promise;
use spmc::{channel, Receiver, Sender};
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<rayon::ThreadBuilder>,
receiver: Receiver<rayon::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) = channel();
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(js_namespace = ["import", "meta"], js_name = url)]
static URL: JsString;
}
URL.clone()
}
#[wasm_bindgen(js_name = numThreads)]
pub fn num_threads(&self) -> usize {
self.num_threads
}
pub fn receiver(&self) -> *const Receiver<rayon::ThreadBuilder> {
&self.receiver
}
pub fn build(&mut self) {
rayon::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<rayon::ThreadBuilder>)
where
Receiver<rayon::ThreadBuilder>: Sync,
{
let receiver = unsafe { &*receiver };
receiver.recv().unwrap_throw().run()
}