@hazae41/mutex
Version:
Rust-like Mutex for TypeScript
1 lines • 7.04 kB
Source Map (JSON)
{"version":3,"file":"mutex.cjs","sources":["../../../../src/mods/mutex/mutex.ts"],"sourcesContent":["import { Future } from \"@hazae41/future\"\nimport { Awaitable } from \"libs/promises/promises.js\"\n\nexport class LockedError extends Error {\n readonly #class = LockedError\n readonly name = this.#class.name\n\n constructor() {\n super(\"Locked\")\n }\n\n}\n\n/**\n * A releasable object\n */\nexport class Lock<T> {\n\n constructor(\n readonly inner: T,\n readonly release: () => void\n ) { }\n\n [Symbol.dispose]() {\n this.release()\n }\n\n get() {\n return this.inner\n }\n\n}\n\n/**\n * A semaphore with some reference and some capacity\n */\nexport class Semaphore<T, N extends number = number> {\n\n #queue = new Array<Future<void>>()\n #count = 0\n\n constructor(\n readonly inner: T,\n readonly capacity: N\n ) { }\n\n static void<N extends number>(capacity: N) {\n return new Semaphore<void, N>(undefined, capacity)\n }\n\n get locked() {\n return this.#count >= this.capacity\n }\n\n get count() {\n return this.#count\n }\n\n get() {\n return this.inner\n }\n\n /**\n * Get and lock or throw\n * @returns \n */\n async getOrThrow(): Promise<Lock<T>> {\n if (this.#count >= this.capacity)\n throw new LockedError()\n\n this.#count++\n\n const dispose = () => {\n this.#queue.shift()?.resolve()\n this.#count--\n }\n\n return new Lock(this.inner, dispose)\n }\n\n /**\n * Get and lock or wait\n * @returns \n */\n async getOrWait(): Promise<Lock<T>> {\n this.#count++\n\n if (this.#count > this.capacity) {\n const future = new Future<void>()\n this.#queue.push(future)\n await future.promise\n }\n\n const dispose = () => {\n this.#queue.shift()?.resolve()\n this.#count--\n }\n\n return new Lock(this.inner, dispose)\n }\n\n /**\n * Run and lock or throw\n * @param callback \n */\n async runOrThrow<R>(callback: (inner: T) => Awaitable<R>): Promise<R> {\n if (this.#count >= this.capacity)\n throw new LockedError()\n\n this.#count++\n\n try {\n return await callback(this.inner)\n } finally {\n this.#queue.shift()?.resolve()\n this.#count--\n }\n }\n\n /**\n * Run and lock or wait\n * @param callback \n */\n async runOrWait<R>(callback: (inner: T) => Awaitable<R>): Promise<R> {\n this.#count++\n\n if (this.#count > this.capacity) {\n const future = new Future<void>()\n this.#queue.push(future)\n await future.promise\n }\n\n try {\n return await callback(this.inner)\n } finally {\n this.#queue.shift()?.resolve()\n this.#count--\n }\n }\n\n}\n\n/**\n * A semaphore but with a capacity of 1\n */\nexport class Mutex<T> {\n\n #semaphore: Semaphore<T, 1>\n\n constructor(\n readonly inner: T\n ) {\n this.#semaphore = new Semaphore(inner, 1)\n }\n\n static void() {\n return new Mutex<void>(undefined)\n }\n\n get locked() {\n return this.#semaphore.locked\n }\n\n get() {\n return this.inner\n }\n\n async getOrThrow(): Promise<Lock<T>> {\n return await this.#semaphore.getOrThrow()\n }\n\n async getOrWait(): Promise<Lock<T>> {\n return await this.#semaphore.getOrWait()\n }\n\n async runOrThrow<R>(callback: (inner: T) => Awaitable<R>): Promise<R> {\n return await this.#semaphore.runOrThrow(callback)\n }\n\n async runOrWait<R>(callback: (inner: T) => Awaitable<R>): Promise<R> {\n return await this.#semaphore.runOrWait(callback)\n }\n\n}"],"names":["future","Future"],"mappings":"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"}