UNPKG

multithreading

Version:

The missing standard library for multithreading in JavaScript (Works in the browser, Node.js, Deno, Bun).

121 lines (120 loc) 6.42 kB
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var _MutexGuard_data, _MutexGuard_mutex, _MutexGuard_released, _Mutex_instances, _a, _Mutex_data, _Mutex_lockState, _Mutex_controller, _Mutex_tryLock, _Mutex_unlock, _Mutex_performBlockingLock, _Mutex_performAsyncLock; import { deserialize, register, Serializable, serialize, toDeserialized, toSerialized, } from "../shared.js"; export const INTERNAL_MUTEX_CONTROLLER = Symbol("Thread.InternalMutexController"); const IDX_LOCK_STATE = 0; const LOCKED = 1; const UNLOCKED = 0; export class MutexGuard { constructor(data, mutex) { _MutexGuard_data.set(this, void 0); _MutexGuard_mutex.set(this, void 0); _MutexGuard_released.set(this, false); __classPrivateFieldSet(this, _MutexGuard_data, data, "f"); __classPrivateFieldSet(this, _MutexGuard_mutex, mutex, "f"); } /** * Internal accessor for Condvar support */ get [(_MutexGuard_data = new WeakMap(), _MutexGuard_mutex = new WeakMap(), _MutexGuard_released = new WeakMap(), INTERNAL_MUTEX_CONTROLLER)]() { return __classPrivateFieldGet(this, _MutexGuard_mutex, "f"); } get value() { if (__classPrivateFieldGet(this, _MutexGuard_released, "f")) throw new Error("Cannot access released mutex data"); return __classPrivateFieldGet(this, _MutexGuard_data, "f"); } [Symbol.dispose]() { if (!__classPrivateFieldGet(this, _MutexGuard_released, "f")) { __classPrivateFieldSet(this, _MutexGuard_released, true, "f"); __classPrivateFieldGet(this, _MutexGuard_mutex, "f").unlock(); } } dispose() { this[Symbol.dispose](); } } export class Mutex extends Serializable { constructor(data, _lockBuffer) { super(); _Mutex_instances.add(this); _Mutex_data.set(this, void 0); _Mutex_lockState.set(this, void 0); _Mutex_controller.set(this, void 0); __classPrivateFieldSet(this, _Mutex_data, data, "f"); __classPrivateFieldSet(this, _Mutex_lockState, _lockBuffer ? new Int32Array(_lockBuffer) : new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT)), "f"); __classPrivateFieldSet(this, _Mutex_controller, { unlock: () => __classPrivateFieldGet(this, _Mutex_instances, "m", _Mutex_unlock).call(this), blockingLock: () => __classPrivateFieldGet(this, _Mutex_instances, "m", _Mutex_performBlockingLock).call(this), lock: () => __classPrivateFieldGet(this, _Mutex_instances, "m", _Mutex_performAsyncLock).call(this), }, "f"); } blockingLock() { __classPrivateFieldGet(this, _Mutex_instances, "m", _Mutex_performBlockingLock).call(this); return new MutexGuard(__classPrivateFieldGet(this, _Mutex_data, "f"), __classPrivateFieldGet(this, _Mutex_controller, "f")); } async lock() { await __classPrivateFieldGet(this, _Mutex_instances, "m", _Mutex_performAsyncLock).call(this); return new MutexGuard(__classPrivateFieldGet(this, _Mutex_data, "f"), __classPrivateFieldGet(this, _Mutex_controller, "f")); } [(_Mutex_data = new WeakMap(), _Mutex_lockState = new WeakMap(), _Mutex_controller = new WeakMap(), _Mutex_instances = new WeakSet(), _Mutex_tryLock = function _Mutex_tryLock() { return (Atomics.compareExchange(__classPrivateFieldGet(this, _Mutex_lockState, "f"), IDX_LOCK_STATE, UNLOCKED, LOCKED) === UNLOCKED); }, _Mutex_unlock = function _Mutex_unlock() { if (Atomics.compareExchange(__classPrivateFieldGet(this, _Mutex_lockState, "f"), IDX_LOCK_STATE, LOCKED, UNLOCKED) !== LOCKED) { throw new Error("Mutex was not locked or locked by another thread"); } Atomics.notify(__classPrivateFieldGet(this, _Mutex_lockState, "f"), IDX_LOCK_STATE, 1); }, _Mutex_performBlockingLock = function _Mutex_performBlockingLock() { while (true) { if (__classPrivateFieldGet(this, _Mutex_instances, "m", _Mutex_tryLock).call(this)) return; Atomics.wait(__classPrivateFieldGet(this, _Mutex_lockState, "f"), IDX_LOCK_STATE, LOCKED); } }, _Mutex_performAsyncLock = /** * Shared logic for async lock. * Used by both public lock() and the Controller (for Condvar) */ async function _Mutex_performAsyncLock() { while (true) { if (__classPrivateFieldGet(this, _Mutex_instances, "m", _Mutex_tryLock).call(this)) return; const result = Atomics.waitAsync(__classPrivateFieldGet(this, _Mutex_lockState, "f"), IDX_LOCK_STATE, LOCKED); if (result.async) { await result.value; } } }, toSerialized)]() { let serializedData; let transfer = []; if (__classPrivateFieldGet(this, _Mutex_data, "f") !== undefined) { [serializedData, transfer] = serialize(__classPrivateFieldGet(this, _Mutex_data, "f")); } return [ [__classPrivateFieldGet(this, _Mutex_lockState, "f").buffer, serializedData], transfer, ]; } static [toDeserialized](obj) { const data = obj[1] !== undefined ? deserialize(obj[1]) : undefined; return new _a(data, obj[0]); } } _a = Mutex; (() => { register(0, _a); })();