some Lock refactoring that I didn't end up needing but still useful
This commit is contained in:
parent
f13f1cd593
commit
89c66699d7
2 changed files with 16 additions and 12 deletions
|
@ -20,7 +20,7 @@ export class Lock {
|
||||||
this._resolve = null;
|
this._resolve = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
take() {
|
tryTake() {
|
||||||
if (!this._promise) {
|
if (!this._promise) {
|
||||||
this._promise = new Promise(resolve => {
|
this._promise = new Promise(resolve => {
|
||||||
this._resolve = resolve;
|
this._resolve = resolve;
|
||||||
|
@ -30,6 +30,12 @@ export class Lock {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async take() {
|
||||||
|
while(!this.tryTake()) {
|
||||||
|
await this.released();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
get isTaken() {
|
get isTaken() {
|
||||||
return !!this._promise;
|
return !!this._promise;
|
||||||
}
|
}
|
||||||
|
@ -52,25 +58,25 @@ export function tests() {
|
||||||
return {
|
return {
|
||||||
"taking a lock twice returns false": assert => {
|
"taking a lock twice returns false": assert => {
|
||||||
const lock = new Lock();
|
const lock = new Lock();
|
||||||
assert.equal(lock.take(), true);
|
assert.equal(lock.tryTake(), true);
|
||||||
assert.equal(lock.isTaken, true);
|
assert.equal(lock.isTaken, true);
|
||||||
assert.equal(lock.take(), false);
|
assert.equal(lock.tryTake(), false);
|
||||||
},
|
},
|
||||||
"can take a released lock again": assert => {
|
"can take a released lock again": assert => {
|
||||||
const lock = new Lock();
|
const lock = new Lock();
|
||||||
lock.take();
|
lock.tryTake();
|
||||||
lock.release();
|
lock.release();
|
||||||
assert.equal(lock.isTaken, false);
|
assert.equal(lock.isTaken, false);
|
||||||
assert.equal(lock.take(), true);
|
assert.equal(lock.tryTake(), true);
|
||||||
},
|
},
|
||||||
"2 waiting for lock, only first one gets it": async assert => {
|
"2 waiting for lock, only first one gets it": async assert => {
|
||||||
const lock = new Lock();
|
const lock = new Lock();
|
||||||
lock.take();
|
lock.tryTake();
|
||||||
|
|
||||||
let first;
|
let first;
|
||||||
lock.released().then(() => first = lock.take());
|
lock.released().then(() => first = lock.tryTake());
|
||||||
let second;
|
let second;
|
||||||
lock.released().then(() => second = lock.take());
|
lock.released().then(() => second = lock.tryTake());
|
||||||
const promise = lock.released();
|
const promise = lock.released();
|
||||||
lock.release();
|
lock.release();
|
||||||
await promise;
|
await promise;
|
||||||
|
|
|
@ -24,12 +24,10 @@ export class LockMap {
|
||||||
async takeLock(key) {
|
async takeLock(key) {
|
||||||
let lock = this._map.get(key);
|
let lock = this._map.get(key);
|
||||||
if (lock) {
|
if (lock) {
|
||||||
while (!lock.take()) {
|
await lock.take();
|
||||||
await lock.released();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
lock = new Lock();
|
lock = new Lock();
|
||||||
lock.take();
|
lock.tryTake();
|
||||||
this._map.set(key, lock);
|
this._map.set(key, lock);
|
||||||
}
|
}
|
||||||
// don't leave old locks lying around
|
// don't leave old locks lying around
|
||||||
|
|
Reference in a new issue