|
| 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