RenaiApp/src/main/modules/mutex/simple-mutex.ts

63 lines
1.6 KiB
TypeScript

/**
* This class implements a simple mutex using a semaphore.
*/
export class SimpleMutex implements MutexInterface {
/**
* This queue is an array of promise resolve functions.
* Calling them signals the corresponding consumer that the lock is now free.
* The resolve functions resolve with the release function.
*/
private queue: Array<(release: Mutex.ReleaseFunction) => void> = [];
/**
* This variable is the semaphore, true if locked, false if not.
*/
private locked: boolean = false;
public acquire(): Promise<Mutex.ReleaseFunction> {
return new Promise<Mutex.ReleaseFunction>((resolve) => {
this.queue.push(resolve);
this.dispatch();
});
}
public release(): void {
this.locked = false;
this.dispatch();
}
public reset(): void {
this.queue = [];
this.locked = false;
}
public isLocked(): boolean {
return this.locked;
}
/**
* This function locks the mutex and calls the next resolve function from the start of the queue.
* The resolve function is called with a release function as parameter which unlocks the mutex and calls the function again
*/
private dispatch(): void {
if (this.locked) {
return;
}
const nextResolve = this.queue.shift();
if (!nextResolve) {
return;
}
// lock the resource
this.locked = true;
// this is the function which gets called by the consumer to release the lock
// it also dispatches the next consumer
const releaseFunction = (): void => {
this.release();
};
// lock the resource and resolve the promise so the consumer can do its thing
nextResolve(releaseFunction);
}
}