node-apparatus
Version:
A mix of common components needed for awesome node experience
52 lines • 2 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SpinWaitLock = exports.SpinWaitLockState = void 0;
var SpinWaitLockState;
(function (SpinWaitLockState) {
SpinWaitLockState[SpinWaitLockState["Acquired"] = 0] = "Acquired";
SpinWaitLockState[SpinWaitLockState["Condition"] = 2] = "Condition";
})(SpinWaitLockState || (exports.SpinWaitLockState = SpinWaitLockState = {}));
/**
* A spin-wait lock. Can be used for single threaded & multi threaded synchronization.
*/
class SpinWaitLock {
/**
* @param serializedLock The serialized lock to use, should pass output of serialize method, default is a new SharedArrayBuffer(4).
*/
constructor(serializedLock = new SharedArrayBuffer(4)) {
this.serializedLock = serializedLock;
this.LOCK_INDEX = 0;
this.lock = new Int32Array(this.serializedLock);
this.contextQueue = new Array();
}
/**
* Serializes the lock, used for passing the lock between threads.
* @returns The serialized lock, a shared buffered instance.
*/
serialize() {
return this.serializedLock;
}
/**
* Acquires the lock.
* @param spinTime The time to wait between attempts to acquire the lock.
* @param spinExitCondition The condition to exit the spin-wait loop.
* @returns A promise that resolves to the state of the lock.
*/
async acquire(spinTime = 100, spinExitCondition = () => false) {
while (Atomics.compareExchange(this.lock, this.LOCK_INDEX, 0, 1) !== 0) {
if (spinExitCondition() === true)
return SpinWaitLockState.Condition;
await new Promise(resolve => setTimeout(resolve, spinTime));
}
return SpinWaitLockState.Acquired;
}
/**
* Releases the lock.
* @returns void
*/
release() {
Atomics.store(this.lock, this.LOCK_INDEX, 0);
}
}
exports.SpinWaitLock = SpinWaitLock;
//# sourceMappingURL=spin-wait-lock.js.map