File size: 2,947 Bytes
0a01d76 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
/*
* Copyright 2022 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// This file is kept similar to workerHelpers.js, but intended to be used in
// a bundlerless ES module environment (which has a few differences).
function waitForMsgType(target, type) {
return new Promise(resolve => {
target.addEventListener('message', function onMsg({ data }) {
if (data == null || data.type !== type) return;
target.removeEventListener('message', onMsg);
resolve(data);
});
});
}
// We need to wait for a specific message because this file is used both
// as a Worker and as a regular script, so it might receive unrelated
// messages on the page.
waitForMsgType(self, 'wasm_bindgen_worker_init').then(async data => {
const pkg = await import(data.mainJS);
await pkg.default(data.module, data.memory);
postMessage({ type: 'wasm_bindgen_worker_ready' });
pkg.wbg_rayon_start_worker(data.receiver);
});
// Note: this is never used, but necessary to prevent a bug in Firefox
// (https://bugzilla.mozilla.org/show_bug.cgi?id=1702191) where it collects
// Web Workers that have a shared WebAssembly memory with the main thread,
// but are not explicitly rooted via a `Worker` instance.
//
// By storing them in a variable, we can keep `Worker` objects around and
// prevent them from getting GC-d.
let _workers;
export async function startWorkers(module, memory, builder) {
if (builder.numThreads() === 0) {
throw new Error(`num_threads must be > 0.`);
}
const workerInit = {
type: 'wasm_bindgen_worker_init',
module,
memory,
receiver: builder.receiver(),
mainJS: builder.mainJS()
};
_workers = await Promise.all(
Array.from({ length: builder.numThreads() }, async () => {
// Self-spawn into a new Worker.
// The script is fetched as a blob so it works even if this script is
// hosted remotely (e.g. on a CDN). This avoids a cross-origin
// security error.
let scriptBlob = await fetch(import.meta.url).then(r => r.blob());
let url = URL.createObjectURL(scriptBlob);
const worker = new Worker(url, {
type: 'module'
});
worker.postMessage(workerInit);
await waitForMsgType(worker, 'wasm_bindgen_worker_ready');
URL.revokeObjectURL(url);
return worker;
})
);
builder.build();
}
|