90 lines
3.3 KiB
JavaScript
90 lines
3.3 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.RWLock = void 0;
|
|
var tslib_1 = require("tslib");
|
|
var assert_1 = tslib_1.__importDefault(require("assert"));
|
|
/**
|
|
* 模拟一个读写锁,用于同步。
|
|
* 注意,千万不要发生自己等自己
|
|
*/
|
|
var RWLock = /** @class */ (function () {
|
|
function RWLock() {
|
|
this.readNumber = 0;
|
|
this.writeNumber = 0;
|
|
this.readWaiter = [];
|
|
this.writeWaiter = [];
|
|
}
|
|
RWLock.prototype.acquire = function (mode) {
|
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
var p, p;
|
|
var _this = this;
|
|
return tslib_1.__generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0:
|
|
if (!(mode === 'S')) return [3 /*break*/, 4];
|
|
_a.label = 1;
|
|
case 1:
|
|
if (!(this.writeNumber > 0)) return [3 /*break*/, 3];
|
|
p = new Promise(function (resolve) { return _this.readWaiter.push(resolve); });
|
|
return [4 /*yield*/, p];
|
|
case 2:
|
|
_a.sent();
|
|
return [3 /*break*/, 1];
|
|
case 3:
|
|
this.readNumber++;
|
|
return [3 /*break*/, 7];
|
|
case 4:
|
|
if (!(this.writeNumber || this.readNumber)) return [3 /*break*/, 6];
|
|
p = new Promise(function (resolve) { return _this.writeWaiter.push(resolve); });
|
|
return [4 /*yield*/, p];
|
|
case 5:
|
|
_a.sent();
|
|
return [3 /*break*/, 4];
|
|
case 6:
|
|
this.writeNumber++;
|
|
_a.label = 7;
|
|
case 7: return [2 /*return*/];
|
|
}
|
|
});
|
|
});
|
|
};
|
|
RWLock.prototype.release = function () {
|
|
var e_1, _a;
|
|
if (this.writeNumber) {
|
|
(0, assert_1.default)(this.writeNumber === 1);
|
|
this.writeNumber = 0;
|
|
if (this.readWaiter.length > 0) {
|
|
try {
|
|
for (var _b = tslib_1.__values(this.readWaiter), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
var f = _c.value;
|
|
f(undefined);
|
|
}
|
|
}
|
|
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
finally {
|
|
try {
|
|
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
}
|
|
finally { if (e_1) throw e_1.error; }
|
|
}
|
|
this.readWaiter = [];
|
|
}
|
|
else if (this.writeWaiter.length > 0) {
|
|
var f = this.writeWaiter.pop();
|
|
f(undefined);
|
|
}
|
|
}
|
|
else {
|
|
(0, assert_1.default)(this.readNumber > 0);
|
|
(0, assert_1.default)(this.readWaiter.length === 0);
|
|
this.readNumber--;
|
|
if (this.readNumber === 0) {
|
|
var f = this.writeWaiter.pop();
|
|
f && f(undefined);
|
|
}
|
|
}
|
|
};
|
|
return RWLock;
|
|
}());
|
|
exports.RWLock = RWLock;
|