Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | 1x 1x 5x 15x 15x 13x 13x 3x 3x 2x 2x 1x 1x 1x 1x 1x 10x 10x 10x 12x 12x 12x 10x 10x 12x 11x 2x 2x | import { Mutex } from "./mutex"
/**
* A class to manage the flow of coroutines using signals.
*/
export class Signal {
private callback: () => Promise<void> = () => Promise.resolve()
private chain(f: () => Promise<void>): void {
const callback = this.callback
this.callback = async () => {
await callback()
await f()
}
}
/**
* Send a signal.
*/
public async notify(): Promise<void> {
await this.callback()
this.callback = () => Promise.resolve()
}
/**
* Wait until a signal is send.
*/
public wait(): Promise<void> {
return new Promise(resolve => {
this.chain(async () => resolve())
})
}
/**
* Repeat a function until a signal is send.
*/
public async repeat(
f: (cancel: Signal) => Promise<void>,
timeout = 0
): Promise<void> {
let cancelled = false
this.chain(async () => {
cancelled = true
})
while (!cancelled) {
const timeout_p = this.timeout(timeout)
await f(this)
await timeout_p
}
}
/**
* Wait for a given time period unless a signal is send.
*/
public timeout(time: number): Promise<void> {
return new Promise<void>(resolve => {
let finished = false
const timeout = setTimeout(() => {
finished = true
resolve()
}, time)
this.chain(async () => {
if (!finished) {
clearTimeout(timeout)
resolve()
}
})
})
}
async while(f: (stop: Mutex) => Promise<void>): Promise<void> {
const stop = new Mutex()
this.chain(async () => {
stop.set(true)
})
while (!stop.get()) {
await f(stop)
}
}
}
|