Buckets:
| /** | |
| * @license | |
| * Copyright 2015 The Emscripten Authors | |
| * SPDX-License-Identifier: MIT | |
| */ | |
| // Pthread Web Worker handling code. | |
| // This code runs only on pthread web workers and handles pthread setup | |
| // and communication with the main thread via postMessage. | |
| #if ASSERTIONS | |
| // Unique ID of the current pthread worker (zero on non-pthread-workers | |
| // including the main thread). | |
| var workerID = 0; | |
| #endif | |
| #if MAIN_MODULE | |
| // Map of modules to be shared with new threads. This gets populated by the | |
| // main thread and shared with all new workers via the initial `load` message. | |
| var sharedModules = {}; | |
| #endif | |
| var startWorker; | |
| if (ENVIRONMENT_IS_PTHREAD) { | |
| // Thread-local guard variable for one-time init of the JS state | |
| var initializedJS = false; | |
| #if LOAD_SOURCE_MAP | |
| // When using postMessage to send an object, it is processed by the structured | |
| // clone algorithm. The prototype, and hence methods, on that object is then | |
| // lost. This function adds back the lost prototype. This does not work with | |
| // nested objects that has prototypes, but it suffices for WasmSourceMap and | |
| // WasmOffsetConverter. | |
| function resetPrototype(constructor, attrs) { | |
| var object = Object.create(constructor.prototype); | |
| return Object.assign(object, attrs); | |
| } | |
| #endif | |
| // Turn unhandled rejected promises into errors so that the main thread will be | |
| // notified about them. | |
| self.onunhandledrejection = (e) => { throw e.reason || e; }; | |
| {{{ asyncIf(ASYNCIFY == 2) }}}function handleMessage(e) { | |
| try { | |
| var msgData = e['data']; | |
| //dbg('msgData: ' + Object.keys(msgData)); | |
| var cmd = msgData.cmd; | |
| if (cmd === 'load') { // Preload command that is called once per worker to parse and load the Emscripten code. | |
| #if ASSERTIONS | |
| workerID = msgData.workerID; | |
| #endif | |
| #if PTHREADS_DEBUG | |
| dbg('worker: loading module') | |
| #endif | |
| // Until we initialize the runtime, queue up any further incoming messages. | |
| let messageQueue = []; | |
| self.onmessage = (e) => messageQueue.push(e); | |
| // And add a callback for when the runtime is initialized. | |
| startWorker = () => { | |
| // Notify the main thread that this thread has loaded. | |
| postMessage({ cmd: 'loaded' }); | |
| // Process any messages that were queued before the thread was ready. | |
| for (let msg of messageQueue) { | |
| handleMessage(msg); | |
| } | |
| // Restore the real message handler. | |
| self.onmessage = handleMessage; | |
| }; | |
| #if MAIN_MODULE | |
| dynamicLibraries = msgData.dynamicLibraries; | |
| sharedModules = msgData.sharedModules; | |
| #if RUNTIME_DEBUG | |
| dbg(`worker: received ${Object.keys(msgData.sharedModules).length} shared modules: ${Object.keys(msgData.sharedModules)}`); | |
| #endif | |
| #endif | |
| // Use `const` here to ensure that the variable is scoped only to | |
| // that iteration, allowing safe reference from a closure. | |
| for (const handler of msgData.handlers) { | |
| // If the main module has a handler for a certain event, but no | |
| // handler exists on the pthread worker, then proxy that handler | |
| // back to the main thread. | |
| if (!Module[handler] || Module[handler].proxy) { | |
| #if RUNTIME_DEBUG | |
| dbg(`worker: installer proxying handler: ${handler}`); | |
| #endif | |
| Module[handler] = (...args) => { | |
| #if RUNTIME_DEBUG | |
| dbg(`worker: calling handler on main thread: ${handler}`); | |
| #endif | |
| postMessage({ cmd: 'callHandler', handler, args: args }); | |
| } | |
| // Rebind the out / err handlers if needed | |
| if (handler == 'print') out = Module[handler]; | |
| if (handler == 'printErr') err = Module[handler]; | |
| } | |
| #if RUNTIME_DEBUG | |
| else dbg(`worker: using thread-local handler: ${handler}`); | |
| #endif | |
| } | |
| #if !WASM_ESM_INTEGRATION | |
| wasmMemory = msgData.wasmMemory; | |
| updateMemoryViews(); | |
| #endif | |
| #if LOAD_SOURCE_MAP | |
| wasmSourceMap = resetPrototype(WasmSourceMap, msgData.wasmSourceMap); | |
| #endif | |
| #if !WASM_ESM_INTEGRATION | |
| #if MINIMAL_RUNTIME | |
| // Pass the shared Wasm module in the Module object for MINIMAL_RUNTIME. | |
| Module['wasm'] = msgData.wasmModule; | |
| loadModule(); | |
| #else | |
| wasmModule = msgData.wasmModule; | |
| #if MODULARIZE == 'instance' | |
| init(); | |
| #else | |
| createWasm(); | |
| run(); | |
| #endif | |
| #endif // MINIMAL_RUNTIME | |
| #endif | |
| } else if (cmd === 'run') { | |
| #if ASSERTIONS | |
| assert(msgData.pthread_ptr); | |
| #endif | |
| // Call inside JS module to set up the stack frame for this pthread in JS module scope. | |
| // This needs to be the first thing that we do, as we cannot call to any C/C++ functions | |
| // until the thread stack is initialized. | |
| establishStackSpace(msgData.pthread_ptr); | |
| // Pass the thread address to wasm to store it for fast access. | |
| __emscripten_thread_init(msgData.pthread_ptr, /*is_main=*/0, /*is_runtime=*/0, /*can_block=*/1, 0, 0); | |
| #if OFFSCREENCANVAS_SUPPORT | |
| PThread.receiveOffscreenCanvases(msgData); | |
| #endif | |
| PThread.threadInitTLS(); | |
| // Await mailbox notifications with `Atomics.waitAsync` so we can start | |
| // using the fast `Atomics.notify` notification path. | |
| __emscripten_thread_mailbox_await(msgData.pthread_ptr); | |
| if (!initializedJS) { | |
| #if EMBIND | |
| #if PTHREADS_DEBUG | |
| dbg(`worker: Pthread 0x${_pthread_self().toString(16)} initializing embind.`); | |
| #endif | |
| // Embind must initialize itself on all threads, as it generates support JS. | |
| // We only do this once per worker since they get reused | |
| __embind_initialize_bindings(); | |
| #endif // EMBIND | |
| initializedJS = true; | |
| } | |
| try { | |
| {{{ awaitIf(ASYNCIFY == 2) }}}invokeEntryPoint(msgData.start_routine, msgData.arg); | |
| } catch(ex) { | |
| if (ex != 'unwind') { | |
| // The pthread "crashed". Do not call `_emscripten_thread_exit` (which | |
| // would make this thread joinable). Instead, re-throw the exception | |
| // and let the top level handler propagate it back to the main thread. | |
| throw ex; | |
| } | |
| #if RUNTIME_DEBUG | |
| dbg(`worker: Pthread 0x${_pthread_self().toString(16)} completed its main entry point with an 'unwind', keeping the worker alive for asynchronous operation.`); | |
| #endif | |
| } | |
| } else if (msgData.target === 'setimmediate') { | |
| // no-op | |
| } else if (cmd === 'checkMailbox') { | |
| if (initializedJS) { | |
| checkMailbox(); | |
| } | |
| } else if (cmd) { | |
| // The received message looks like something that should be handled by this message | |
| // handler, (since there is a cmd field present), but is not one of the | |
| // recognized commands: | |
| err(`worker: received unknown command ${cmd}`); | |
| err(msgData); | |
| } | |
| } catch(ex) { | |
| #if ASSERTIONS | |
| err(`worker: onmessage() captured an uncaught exception: ${ex}`); | |
| if (ex?.stack) err(ex.stack); | |
| #endif | |
| __emscripten_thread_crashed(); | |
| throw ex; | |
| } | |
| }; | |
| self.onmessage = handleMessage; | |
| } // ENVIRONMENT_IS_PTHREAD | |
Xet Storage Details
- Size:
- 7.15 kB
- Xet hash:
- 4d75a96f28c95e49da56c4f63f2a14b29ad21d4a5362de55db415726eb8b1a3c
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.