You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Web Locks: a request waiting for a lock stays pending after the worker thread holding the lock exits #67216
import{Worker}from"node:worker_threads";import{setTimeoutassleep}from"node:timers/promises";// A worker thread takes a lock and then exits while holding it.constholder=newWorker(` const { parentPort } = require("node:worker_threads"); navigator.locks.request("my-lock", () => { parentPort.postMessage("held"); parentPort.once("message", () => process.exit()); return new Promise(() => {}); }); `,{eval: true},);awaitnewPromise((resolve)=>holder.once("message",resolve));constwaiter=navigator.locks.request("my-lock",()=>"granted");holder.postMessage("exit");awaitnewPromise((resolve)=>holder.once("exit",resolve));console.log(awaitPromise.race([waiter,sleep(1000).then(()=>"still waiting")]));// Any unrelated lock request grants it.awaitnavigator.locks.request("other",{ifAvailable: true},()=>{});console.log(awaitPromise.race([waiter,sleep(1000).then(()=>"still waiting")]));
How often does it reproduce? Is there a required condition?
Always, when the thread holding the lock ends through process.exit() or an uncaught exception, or calls process.exit() right after releasing the lock. The same happens when the waiting request was made in another worker thread. worker.terminate() didn't reproduce it here.
What is the expected behavior? Why is that the expected behavior?
granted on the first line. Ending the thread releases its locks, so the waiting request should be granted, as it is in browsers when a worker holding a lock ends.
What do you see instead?
still waiting
granted
The request stays pending until any thread requests any lock.
Additional information
LockManager::CleanupEnvironment in src/node_locks.cc removes the ending environment's held locks but doesn't process the pending queue, as ReleaseLockAndProcessQueue does. Found while running Evolu (https://www.evolu.dev), a local-first platform, on Node.js worker threads. There, a thread waiting for a database lock would hang forever when the thread holding it crashed.
Activity