"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const promiseUtils = require("./lib-utils-promise-utils.cjs");
const cancellation = require("../../_virtual/cancellation.cjs");
class DefaultWorkspaceLock {
  constructor() {
    this.previousTokenSource = new cancellation.cancellationExports.CancellationTokenSource();
    this.writeQueue = [];
    this.readQueue = [];
    this.done = true;
  }
  write(action) {
    this.cancelWrite();
    const tokenSource = promiseUtils.startCancelableOperation();
    this.previousTokenSource = tokenSource;
    return this.enqueue(this.writeQueue, action, tokenSource.token);
  }
  read(action) {
    return this.enqueue(this.readQueue, action);
  }
  enqueue(queue, action, cancellationToken = cancellation.cancellationExports.CancellationToken.None) {
    const deferred = new promiseUtils.Deferred();
    const entry = {
      action,
      deferred,
      cancellationToken
    };
    queue.push(entry);
    this.performNextOperation();
    return deferred.promise;
  }
  async performNextOperation() {
    if (!this.done) {
      return;
    }
    const entries = [];
    if (this.writeQueue.length > 0) {
      entries.push(this.writeQueue.shift());
    } else if (this.readQueue.length > 0) {
      entries.push(...this.readQueue.splice(0, this.readQueue.length));
    } else {
      return;
    }
    this.done = false;
    await Promise.all(entries.map(async ({ action, deferred, cancellationToken }) => {
      try {
        const result = await Promise.resolve().then(() => action(cancellationToken));
        deferred.resolve(result);
      } catch (err) {
        if (promiseUtils.isOperationCancelled(err)) {
          deferred.resolve(void 0);
        } else {
          deferred.reject(err);
        }
      }
    }));
    this.done = true;
    this.performNextOperation();
  }
  cancelWrite() {
    this.previousTokenSource.cancel();
  }
}
exports.DefaultWorkspaceLock = DefaultWorkspaceLock;
//# sourceMappingURL=lib-workspace-workspace-lock.cjs.map
