UNPKG

lavva.exalushome

Version:

Library implementing communication and abstraction layers for ExalusHome system

51 lines 1.95 kB
export class AsyncSemaphore { constructor(initialCount) { this.initialCount = initialCount; this._running = 0; this._waiting = []; this.Take = () => { if (this._waiting.length > 0 && this._running < this.initialCount) { this._running++; const task = this._waiting.shift(); task === null || task === void 0 ? void 0 : task.Resolve({ Release: this.Release }); } }; this.IsLocked = () => { return this._running > 0; }; /** * Acquire a lock on the target resource. * @returns a function to release the lock, it is critical that this function is called when the task is finished with the resource. */ this.AcquireAsync = () => { if (this._running < this.initialCount) { this._running++; return Promise.resolve({ Release: this.Release }); } return new Promise((resolve, reject) => { this._waiting.push({ Resolve: resolve, Reject: reject }); }); }; this.Release = () => { if (this._running === 0) { throw new Error('Release called more times than AcquireAsync'); } this._running--; this.Take(); }; /** * Purge all waiting tasks from the Semaphore instance */ this.Purge = () => { this._waiting.forEach(task => { task.Reject(new Error('The semaphore was purged and as a result this task has been cancelled')); }); this._running = 0; this._waiting = []; }; if (initialCount < 1) { throw new Error(`The semaphore was created with a max value of ${initialCount} but the max value cannot be less than 1`); } } } //# sourceMappingURL=AsyncSemaphore.js.map