69 lines
2.1 KiB
JavaScript
69 lines
2.1 KiB
JavaScript
![]() |
"use strict";
|
||
|
/* --------------------------------------------------------------------------------------------
|
||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||
|
* ------------------------------------------------------------------------------------------ */
|
||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||
|
exports.Semaphore = void 0;
|
||
|
const ral_1 = require("./ral");
|
||
|
class Semaphore {
|
||
|
constructor(capacity = 1) {
|
||
|
if (capacity <= 0) {
|
||
|
throw new Error('Capacity must be greater than 0');
|
||
|
}
|
||
|
this._capacity = capacity;
|
||
|
this._active = 0;
|
||
|
this._waiting = [];
|
||
|
}
|
||
|
lock(thunk) {
|
||
|
return new Promise((resolve, reject) => {
|
||
|
this._waiting.push({ thunk, resolve, reject });
|
||
|
this.runNext();
|
||
|
});
|
||
|
}
|
||
|
get active() {
|
||
|
return this._active;
|
||
|
}
|
||
|
runNext() {
|
||
|
if (this._waiting.length === 0 || this._active === this._capacity) {
|
||
|
return;
|
||
|
}
|
||
|
(0, ral_1.default)().timer.setImmediate(() => this.doRunNext());
|
||
|
}
|
||
|
doRunNext() {
|
||
|
if (this._waiting.length === 0 || this._active === this._capacity) {
|
||
|
return;
|
||
|
}
|
||
|
const next = this._waiting.shift();
|
||
|
this._active++;
|
||
|
if (this._active > this._capacity) {
|
||
|
throw new Error(`To many thunks active`);
|
||
|
}
|
||
|
try {
|
||
|
const result = next.thunk();
|
||
|
if (result instanceof Promise) {
|
||
|
result.then((value) => {
|
||
|
this._active--;
|
||
|
next.resolve(value);
|
||
|
this.runNext();
|
||
|
}, (err) => {
|
||
|
this._active--;
|
||
|
next.reject(err);
|
||
|
this.runNext();
|
||
|
});
|
||
|
}
|
||
|
else {
|
||
|
this._active--;
|
||
|
next.resolve(result);
|
||
|
this.runNext();
|
||
|
}
|
||
|
}
|
||
|
catch (err) {
|
||
|
this._active--;
|
||
|
next.reject(err);
|
||
|
this.runNext();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
exports.Semaphore = Semaphore;
|