UNPKG

@nomicfoundation/ethereumjs-util

Version:
43 lines (37 loc) 1.63 kB
// Based on https://github.com/jsoendermann/semaphore-async-await/blob/master/src/Semaphore.ts export class Lock { private permits: number = 1 private promiseResolverQueue: Array<(v: boolean) => void> = [] /** * Returns a promise used to wait for a permit to become available. This method should be awaited on. * @returns A promise that gets resolved when execution is allowed to proceed. */ public async acquire(): Promise<boolean> { if (this.permits > 0) { this.permits -= 1 return Promise.resolve(true) } // If there is no permit available, we return a promise that resolves once the semaphore gets // signaled enough times that permits is equal to one. return new Promise<boolean>((resolver) => this.promiseResolverQueue.push(resolver)) } /** * Increases the number of permits by one. If there are other functions waiting, one of them will * continue to execute in a future iteration of the event loop. */ public release(): void { this.permits += 1 if (this.permits > 1 && this.promiseResolverQueue.length > 0) { // eslint-disable-next-line no-console console.warn('Lock.permits should never be > 0 when there is someone waiting.') } else if (this.permits === 1 && this.promiseResolverQueue.length > 0) { // If there is someone else waiting, immediately consume the permit that was released // at the beginning of this function and let the waiting function resume. this.permits -= 1 const nextResolver = this.promiseResolverQueue.shift() if (nextResolver) { nextResolver(true) } } } }