UNPKG

@bsv/wallet-toolbox-client

Version:
88 lines 2.76 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SingleWriterMultiReaderLock = void 0; /** * A reader-writer lock to manage concurrent access. * Allows multiple readers or one writer at a time. */ class SingleWriterMultiReaderLock { constructor() { this.readers = 0; this.writerActive = false; this.readerQueue = []; this.writerQueue = []; } checkQueues() { if (this.writerActive || this.readers > 0) return; if (this.writerQueue.length > 0) { // If there are waiting writers and no active readers or writers, start the next writer const resolve = this.writerQueue.shift(); resolve(); } else if (this.readerQueue.length > 0) { // If there are waiting readers and no waiting writers, start all readers const readers = this.readerQueue.splice(0); for (const resolve of readers) { resolve(); } } } async withReadLock(fn) { if (!this.writerActive && this.writerQueue.length === 0) { // Fast path: no active writer or waiting writers, proceed immediately this.readers++; try { return await fn(); } finally { this.readers--; this.checkQueues(); } } else { // Queue the reader until writers are done const promise = new Promise(resolve => { this.readerQueue.push(resolve); }); await promise; this.readers++; try { return await fn(); } finally { this.readers--; this.checkQueues(); } } } async withWriteLock(fn) { if (!this.writerActive && this.readers === 0) { // Fast path: no active writer or readers, proceed immediately this.writerActive = true; try { return await fn(); } finally { this.writerActive = false; this.checkQueues(); } } else { const promise = new Promise(resolve => { this.writerQueue.push(resolve); }); await promise; this.writerActive = true; try { return await fn(); } finally { this.writerActive = false; this.checkQueues(); } } } } exports.SingleWriterMultiReaderLock = SingleWriterMultiReaderLock; //# sourceMappingURL=SingleWriterMultiReaderLock.js.map