1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 | Object.defineProperty(exports, "__esModule", { value: true });
|
9 | const list_1 = require("./list");
|
10 | const cancellation_1 = require("./cancellation");
|
11 | const utils_1 = require("./utils");
|
12 | const adapter_1 = require("./adapter");
|
13 | const MAX_INT32 = -1 >>> 1;
|
14 |
|
15 |
|
16 |
|
17 |
|
18 | class Semaphore {
|
19 | |
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 | constructor(initialCount, maxCount) {
|
26 | this._waiters = new list_1.LinkedList();
|
27 | if (utils_1.isMissing(maxCount))
|
28 | maxCount = MAX_INT32;
|
29 | if (!utils_1.isNumber(initialCount))
|
30 | throw new TypeError("Number expected: initialCount.");
|
31 | if (!utils_1.isNumber(maxCount))
|
32 | throw new TypeError("Number expected: maxCount.");
|
33 | if ((initialCount |= 0) < 0)
|
34 | throw new RangeError("Argument out of range: initialCount.");
|
35 | if ((maxCount |= 0) < 1)
|
36 | throw new RangeError("Argument out of range: maxCount.");
|
37 | if (initialCount > maxCount)
|
38 | throw new RangeError("Argument out of range: initialCount.");
|
39 | this._currentCount = initialCount;
|
40 | this._maxCount = maxCount;
|
41 | }
|
42 | |
43 |
|
44 |
|
45 |
|
46 | get count() {
|
47 | return this._currentCount;
|
48 | }
|
49 | |
50 |
|
51 |
|
52 |
|
53 |
|
54 | wait(token) {
|
55 | return new Promise((resolve, reject) => {
|
56 | const _token = adapter_1.getToken(token);
|
57 | _token.throwIfCancellationRequested();
|
58 | if (this._currentCount > 0) {
|
59 | this._currentCount--;
|
60 | resolve();
|
61 | return;
|
62 | }
|
63 | const node = this._waiters.push(() => {
|
64 | registration.unregister();
|
65 | if (_token.cancellationRequested) {
|
66 | reject(new cancellation_1.CancelError());
|
67 | }
|
68 | else {
|
69 | resolve();
|
70 | }
|
71 | });
|
72 | const registration = _token.register(() => {
|
73 | if (node.list) {
|
74 | node.list.deleteNode(node);
|
75 | reject(new cancellation_1.CancelError());
|
76 | }
|
77 | });
|
78 | });
|
79 | }
|
80 | |
81 |
|
82 |
|
83 |
|
84 |
|
85 | release(count) {
|
86 | if (utils_1.isMissing(count))
|
87 | count = 1;
|
88 | if (!utils_1.isNumber(count))
|
89 | throw new TypeError("Number expected: count.");
|
90 | if ((count |= 0) < 1)
|
91 | throw new RangeError("Argument out of range: count.");
|
92 | if (this._maxCount - this._currentCount < count)
|
93 | throw new RangeError("Argument out of range: count.");
|
94 | while (count > 0) {
|
95 | count--;
|
96 | const resolve = this._waiters.shift();
|
97 | if (resolve) {
|
98 | resolve();
|
99 | }
|
100 | else {
|
101 | this._currentCount++;
|
102 | }
|
103 | }
|
104 | }
|
105 | }
|
106 | exports.Semaphore = Semaphore;
|