mutex-ts
Version:
This package provides two classes for managing locks: `Mutex` and `MutexRW`. These locks can be used to control access to critical sections in a multi-threaded or asynchronous environment.
125 lines (124 loc) • 3.48 kB
JavaScript
var m = Object.defineProperty;
var l = (t, s, e) => s in t ? m(t, s, { enumerable: !0, configurable: !0, writable: !0, value: e }) : t[s] = e;
var i = (t, s, e) => (l(t, typeof s != "symbol" ? s + "" : s, e), e);
function a() {
}
class c {
constructor() {
i(this, "m_lastPromise", Promise.resolve());
}
/**
* Acquire lock
* @param [bypass=false] option to skip lock acquisition
*/
async obtain(s = !1) {
let e = a;
if (s)
return e;
const r = this.m_lastPromise;
return this.m_lastPromise = new Promise((o) => e = o), await r, e;
}
/**
* Creates a lock object that can be used with the `using` statement.
* The `using` statement ensures that the lock is released even if an error occurs within the block.
*
* @returns An object with a `Symbol.dispose` method that releases the lock when called.
*
* @example
* ```typescript
* async function main() {
* const mutex = new Mutex();
* {
* using _ = await mutex.lock();
* // Critical section
* // The lock is automatically released when the block exits
* }
* }
* ```
*/
async lock(s = !1) {
return {
[Symbol.dispose]: await this.obtain(s)
};
}
}
class P {
constructor() {
i(this, "m_nextRWPromise", Promise.resolve());
i(this, "m_lastRWPromise", Promise.resolve());
i(this, "m_lastROPromise", Promise.resolve());
i(this, "roAccessCnt", 0);
i(this, "rwAccess", !1);
}
/**
* Acquire read lock
*/
async obtainRO() {
for (; this.rwAccess; )
await this.m_lastRWPromise;
++this.roAccessCnt;
let s = a;
const e = new Promise((r) => s = r);
return this.m_lastROPromise = Promise.all([e, this.m_lastROPromise]), e.then(() => --this.roAccessCnt), s;
}
/**
* Creates a read lock object that can be used with the `using` statement.
* The `using` statement ensures that the lock is released even if an error occurs within the block.
*
* @returns An object with a `Symbol.dispose` method that releases the lock when called.
*
* @example
* ```typescript
* async function main() {
* const mutex = new MutexRW();
* {
* using _ = await mutex.lockRO();
* // Critical section
* // The lock is automatically released when the block exits
* }
* }
* ```
*/
async lockRO() {
return {
[Symbol.dispose]: await this.obtainRO()
};
}
/**
* Acquire write lock
*/
async obtainRW() {
let s = a;
const e = this.m_nextRWPromise, r = new Promise((o) => s = o);
for (this.m_nextRWPromise = r, await e; this.roAccessCnt; )
await this.m_lastROPromise;
return this.rwAccess = !0, this.m_lastRWPromise = r, this.m_lastRWPromise.then(() => this.rwAccess = !1), s;
}
/**
* Creates a write lock object that can be used with the `using` statement.
* The `using` statement ensures that the lock is released even if an error occurs within the block.
*
* @returns An object with a `Symbol.dispose` method that releases the lock when called.
*
* @example
* ```typescript
* async function main() {
* const mutex = new MutexRW();
* {
* using _ = await mutex.lockRW();
* // Critical section
* // The lock is automatically released when the block exits
* }
* }
* ```
*/
async lockRW() {
return {
[Symbol.dispose]: await this.obtainRW()
};
}
}
export {
c as Mutex,
P as MutexRW
};