mirror of
https://github.com/vale981/tridactyl
synced 2025-03-05 17:41:40 -05:00
Add withlock function with timeout
This commit is contained in:
parent
6f6c9e0cd0
commit
84d258c293
1 changed files with 27 additions and 7 deletions
|
@ -2,6 +2,9 @@
|
|||
import {messageAllTabs} from "@src/lib/messaging"
|
||||
|
||||
import {v1 as uuid} from "uuid"
|
||||
import * as Logging from "@src/lib/logging"
|
||||
|
||||
const logger = new Logging.Logger("locks")
|
||||
|
||||
export const OWNED_LOCKS = new Set()
|
||||
|
||||
|
@ -11,24 +14,41 @@ export const ID = uuid()
|
|||
|
||||
const now = () => (new Date()).getTime() + Math.random() // getTime is accurate only to ms, so fake microseconds with random
|
||||
|
||||
export async function acquire(lockname: string, timeout= 2000) {
|
||||
export async function acquire(lockname: string) {
|
||||
if (OWNED_LOCKS.has(lockname) || DESIRED_LOCKS.hasOwnProperty(lockname)) return;
|
||||
const time = now()
|
||||
|
||||
DESIRED_LOCKS[lockname] = time
|
||||
|
||||
await Promise.race([
|
||||
Promise.all([
|
||||
browser.runtime.sendMessage({type: "lock", command: "acquire", args: [lockname, time, ID]}),
|
||||
messageAllTabs("lock", "acquire", [lockname, time, ID]),
|
||||
]),
|
||||
new Promise(resolve => setTimeout(resolve, timeout)), // Take lock anyway after timeout
|
||||
await Promise.all([
|
||||
browser.runtime.sendMessage({type: "lock", command: "acquire", args: [lockname, time, ID]}),
|
||||
messageAllTabs("lock", "acquire", [lockname, time, ID]),
|
||||
])
|
||||
|
||||
delete DESIRED_LOCKS[lockname]
|
||||
OWNED_LOCKS.add(lockname)
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute func after acquiring a named lock. If func takes longer than timeout, release the lock early.
|
||||
* Returns the value of func.
|
||||
*/
|
||||
export async function withlock(lockname: string, func, timeout= 2000) {
|
||||
await acquire(lockname)
|
||||
const p = (async () => func())() // Ensure function is promisified
|
||||
const a = await Promise.race([
|
||||
p,
|
||||
new Promise(resolve => setTimeout(
|
||||
() => {
|
||||
resolve("ERROR: LOST THE RACE")
|
||||
},
|
||||
timeout)), // Release the lock anyway after timeout
|
||||
])
|
||||
if (a === "ERROR: LOST THE RACE") {logger.warning("lock " + lockname + " was released early")}
|
||||
release(lockname)
|
||||
return p
|
||||
}
|
||||
|
||||
export async function release(lockname: string) {
|
||||
OWNED_LOCKS.delete(lockname)
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue