|
| 1 | +import { Semaphore } from "../semaphore"; |
1 | 2 | import { Synchronizer } from "../synchronizer.interface"; |
2 | 3 |
|
| 4 | +/** |
| 5 | + * A mutex to manage "concurrency in Javascript" (as mentioned in the mozilla documentation). |
| 6 | + * |
| 7 | + * Implementation's note: the mutex simply use an internal semaphore. |
| 8 | + * |
| 9 | + * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#promise_concurrency |
| 10 | + */ |
3 | 11 | export class Mutex implements Synchronizer { |
| 12 | + /** |
| 13 | + * The internal semaphore for mutex implementation |
| 14 | + */ |
| 15 | + private readonly semaphore = new Semaphore(1); |
| 16 | + |
4 | 17 | /** |
5 | 18 | * @returns if the current mutex is currently locked |
6 | 19 | */ |
7 | 20 | public get isLocked(): boolean { |
8 | | - throw new Error("Not implemented yet"); |
| 21 | + return this.queueLength !== 0; |
9 | 22 | } |
10 | 23 |
|
11 | 24 | /** |
12 | 25 | * @inheritDoc |
13 | 26 | */ |
14 | 27 | public get queueLength(): number { |
15 | | - throw new Error("Not implemented yet"); |
| 28 | + return this.semaphore.queueLength; |
16 | 29 | } |
17 | 30 |
|
18 | 31 | /** |
19 | 32 | * Locks this mutex |
20 | 33 | * |
| 34 | + * @throws {ConcurrencyInterruptedException} when the mutex is interrupted |
21 | 35 | * @returns a promise when the lock has been set |
22 | 36 | */ |
23 | 37 | public lock(): Promise<void> { |
24 | | - throw new Error("Not implemented yet"); |
| 38 | + return this.semaphore.acquire(1); |
25 | 39 | } |
26 | 40 |
|
27 | 41 | /** |
28 | | - * Locks this mutex within a time limit. |
| 42 | + * Locks this mutex within a time limit |
29 | 43 | * |
30 | | - * Throws an error if the given time exceeds. |
| 44 | + * Throws an error if the given time exceeds |
31 | 45 | * |
32 | 46 | * @param timeout maximum time (in ms) to lock |
| 47 | + * @throws {ConcurrencyExceedTimeoutException} when the time limit exceeds |
| 48 | + * @throws {ConcurrencyInterruptedException} when the mutex is interrupted |
33 | 49 | * @returns a promise when the lock has been set |
34 | 50 | */ |
35 | 51 | public tryLock(timeout: number): Promise<void> { |
36 | | - throw new Error("Not implemented yet"); |
| 52 | + return this.semaphore.tryAcquire(timeout, 1); |
37 | 53 | } |
38 | 54 |
|
39 | 55 | /** |
40 | 56 | * Unlocks this mutex |
41 | 57 | */ |
42 | 58 | public unlock() { |
43 | | - throw new Error("Not implemented yet"); |
| 59 | + this.semaphore.release(); |
44 | 60 | } |
45 | 61 |
|
46 | 62 | /** |
47 | | - * @inheritDoc |
| 63 | + * Interrupts all awaiting "Threads" with an [exception]{@link ConcurrencyInterruptedException}. |
| 64 | + * |
| 65 | + * @param reason The reason why this mutex is being interrupted |
48 | 66 | */ |
49 | 67 | public interrupt(reason: unknown) { |
50 | | - throw new Error("Not implemented yet"); |
| 68 | + this.semaphore.interrupt(reason, 1); |
51 | 69 | } |
52 | 70 | } |
0 commit comments