multithreading
Version:
The missing standard library for multithreading in JavaScript (Works in the browser, Node.js, Deno, Bun).
71 lines (70 loc) • 3.46 kB
JavaScript
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 _a, _Condvar_atomic;
import { INTERNAL_MUTEX_CONTROLLER } from "./mutex.js";
import { register, Serializable, toDeserialized, toSerialized, } from "../shared.js";
const IDX_NOTIFY_SEQ = 0;
const SEQ_INCREMENT = 1;
const NOTIFY_ONE = 1;
const NOTIFY_ALL = Infinity;
export class Condvar extends Serializable {
constructor(_buffer) {
super();
_Condvar_atomic.set(this, void 0);
__classPrivateFieldSet(this, _Condvar_atomic, new Int32Array(_buffer ?? new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT)), "f");
}
blockingWait(guard) {
const controller = guard[INTERNAL_MUTEX_CONTROLLER];
const seq = Atomics.load(__classPrivateFieldGet(this, _Condvar_atomic, "f"), IDX_NOTIFY_SEQ);
controller.unlock();
Atomics.wait(__classPrivateFieldGet(this, _Condvar_atomic, "f"), IDX_NOTIFY_SEQ, seq);
controller.blockingLock();
}
/**
* Asynchronously waits for a notification. Safe to use on the Main Thread.
* @param guard The MutexGuard protecting the shared state.
*/
async wait(guard) {
const controller = guard[INTERNAL_MUTEX_CONTROLLER];
const seq = Atomics.load(__classPrivateFieldGet(this, _Condvar_atomic, "f"), IDX_NOTIFY_SEQ);
controller.unlock();
const result = Atomics.waitAsync(__classPrivateFieldGet(this, _Condvar_atomic, "f"), IDX_NOTIFY_SEQ, seq);
if (result.async) {
await result.value;
}
await controller.lock();
}
/**
* Wakes up one blocked thread waiting on this Condvar.
*/
notifyOne() {
Atomics.add(__classPrivateFieldGet(this, _Condvar_atomic, "f"), IDX_NOTIFY_SEQ, SEQ_INCREMENT);
Atomics.notify(__classPrivateFieldGet(this, _Condvar_atomic, "f"), IDX_NOTIFY_SEQ, NOTIFY_ONE);
}
/**
* Wakes up all blocked threads waiting on this Condvar.
*/
notifyAll() {
Atomics.add(__classPrivateFieldGet(this, _Condvar_atomic, "f"), IDX_NOTIFY_SEQ, SEQ_INCREMENT);
Atomics.notify(__classPrivateFieldGet(this, _Condvar_atomic, "f"), IDX_NOTIFY_SEQ, NOTIFY_ALL);
}
[(_Condvar_atomic = new WeakMap(), toSerialized)]() {
return [__classPrivateFieldGet(this, _Condvar_atomic, "f").buffer];
}
static [toDeserialized](obj) {
return new _a(obj);
}
}
_a = Condvar;
(() => {
register(1, _a);
})();