Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | 476x 476x 476x 64x 45x 19x 19x 64x 64x 64x 64x 19x 45x | /**
* Runs async tasks with at most `max` in flight at once (#1817).
*
* Header preprocessing starts one C preprocessor process per header, and a
* large embedded project includes hundreds. Unbounded, they would all start
* together.
*
* A finishing task hands its slot straight to the next waiter rather than
* releasing it. Releasing first would let a caller arriving in between take the
* slot too, and the count would briefly exceed `max`.
*/
class ConcurrencyLimit {
static create(max: number): <T>(task: () => Promise<T>) => Promise<T> {
let active = 0;
const waiting: Array<() => void> = [];
return async <T>(task: () => Promise<T>): Promise<T> => {
if (active < max) {
active += 1;
} else {
await new Promise<void>((resolve) => {
waiting.push(resolve);
});
}
try {
return await task();
} finally {
const next = waiting.shift();
if (next) {
next();
} else {
active -= 1;
}
}
};
}
}
export default ConcurrencyLimit;
|