Live video on the AT Protocol
1type Cont = () => void;
2
3export class Lock {
4 private readonly queue: Cont[] = [];
5 private acquired = false;
6
7 public async acquire(): Promise<void> {
8 if (!this.acquired) {
9 this.acquired = true;
10 } else {
11 return new Promise<void>((resolve, _) => {
12 this.queue.push(resolve);
13 });
14 }
15 }
16
17 public async release(): Promise<void> {
18 if (this.queue.length === 0 && this.acquired) {
19 this.acquired = false;
20 return;
21 }
22
23 const continuation = this.queue.shift();
24 return new Promise((res: Cont) => {
25 continuation!();
26 res();
27 });
28 }
29
30 public async critical<T>(task: () => Promise<T>) {
31 await this.acquire();
32 try {
33 return await task();
34 } finally {
35 await this.release();
36 }
37 }
38}