tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Mutex.ts (1136B)


      1 /**
      2 * @license
      3 * Copyright 2024 Google Inc.
      4 * SPDX-License-Identifier: Apache-2.0
      5 */
      6 import {Deferred} from './Deferred.js';
      7 import {disposeSymbol} from './disposable.js';
      8 
      9 /**
     10 * @internal
     11 */
     12 export class Mutex {
     13  static Guard = class Guard {
     14    #mutex: Mutex;
     15    #onRelease?: () => void;
     16    constructor(mutex: Mutex, onRelease?: () => void) {
     17      this.#mutex = mutex;
     18      this.#onRelease = onRelease;
     19    }
     20    [disposeSymbol](): void {
     21      this.#onRelease?.();
     22      return this.#mutex.release();
     23    }
     24  };
     25 
     26  #locked = false;
     27  #acquirers: Array<() => void> = [];
     28 
     29  // This is FIFO.
     30  async acquire(
     31    onRelease?: () => void,
     32  ): Promise<InstanceType<typeof Mutex.Guard>> {
     33    if (!this.#locked) {
     34      this.#locked = true;
     35      return new Mutex.Guard(this);
     36    }
     37    const deferred = Deferred.create<void>();
     38    this.#acquirers.push(deferred.resolve.bind(deferred));
     39    await deferred.valueOrThrow();
     40    return new Mutex.Guard(this, onRelease);
     41  }
     42 
     43  release(): void {
     44    const resolve = this.#acquirers.shift();
     45    if (!resolve) {
     46      this.#locked = false;
     47      return;
     48    }
     49    resolve();
     50  }
     51 }