UNPKG

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
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 };