diff --git a/packages/client/src/utils/lock.ts b/packages/client/src/utils/lock.ts index 0e066745..18330ba0 100644 --- a/packages/client/src/utils/lock.ts +++ b/packages/client/src/utils/lock.ts @@ -1,24 +1,36 @@ +type LockInfo = [Promise, () => void] +interface OneWayLinkedList { + v: T + n?: OneWayLinkedList +} + /** @internal */ export class Lock { - private _prom: Promise | null = null - private _unlock: (() => void) | null = null - - constructor() { - this._prom = null - this._unlock = null - } + private _first?: OneWayLinkedList + private _last?: OneWayLinkedList async acquire(): Promise { - if (this._prom) await this._prom - this._prom = new Promise((resolve) => { - this._unlock = resolve + while (this._first) { + await this._first.v[0] + } + + let unlock: () => void + const prom = new Promise((resolve) => { + unlock = resolve }) + + if (this._last) { + this._last.n = { v: [prom, unlock!] } + this._last = this._last.n + } else { + this._first = this._last = { v: [prom, unlock!] } + } } release(): void { - if (!this._unlock) return - this._unlock() - this._prom = null - this._unlock = null + if (!this._first) throw new Error('Nothing to release') + this._first.v[1]() + this._first = this._first.n + if (!this._first) this._last = undefined } }