| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364 |
- /*
- MIT License http://www.opensource.org/licenses/mit-license.php
- Author Tobias Koppers @sokra
- */
- "use strict";
- /**
- * Simple counting semaphore used to limit how many asynchronous tasks may run
- * concurrently.
- */
- class Semaphore {
- /**
- * Initializes the semaphore with the number of permits that may be held at
- * the same time.
- * @param {number} available the amount available number of "tasks"
- * in the Semaphore
- */
- constructor(available) {
- this.available = available;
- /** @type {(() => void)[]} */
- this.waiters = [];
- /** @private */
- this._continue = this._continue.bind(this);
- }
- /**
- * Acquires a permit for the callback immediately when one is available or
- * queues the callback until another task releases its permit.
- * @param {() => void} callback function block to capture and run
- * @returns {void}
- */
- acquire(callback) {
- if (this.available > 0) {
- this.available--;
- callback();
- } else {
- this.waiters.push(callback);
- }
- }
- /**
- * Releases a permit and schedules the next waiting callback, if any.
- */
- release() {
- this.available++;
- if (this.waiters.length > 0) {
- process.nextTick(this._continue);
- }
- }
- /**
- * Drains the next waiting callback after a permit becomes available.
- */
- _continue() {
- if (this.available > 0 && this.waiters.length > 0) {
- this.available--;
- const callback = /** @type {(() => void)} */ (this.waiters.pop());
- callback();
- }
- }
- }
- module.exports = Semaphore;
|