mirror of
https://github.com/nodejs/node.git
synced 2025-08-15 13:48:44 +02:00

PR-URL: https://github.com/nodejs/node/pull/58666 Fixes: https://github.com/nodejs/node/pull/36502 Refs: https://w3c.github.io/web-locks Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Ethan Arrowood <ethan@arrowood.dev> Reviewed-By: Filip Skokan <panva.ip@gmail.com> Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>
92 lines
3.2 KiB
JavaScript
92 lines
3.2 KiB
JavaScript
'use strict';
|
|
|
|
require('../common');
|
|
const { describe, it } = require('node:test');
|
|
const assert = require('node:assert');
|
|
const { Worker } = require('worker_threads');
|
|
|
|
describe('Web Locks - query missing WPT tests', () => {
|
|
it('should report different ids for held locks from different contexts', async () => {
|
|
const worker = new Worker(`
|
|
const { parentPort } = require('worker_threads');
|
|
|
|
navigator.locks.request('different-contexts-resource', { mode: 'shared' }, async (lock) => {
|
|
const state = await navigator.locks.query();
|
|
const heldLocks = state.held.filter(l => l.name === 'different-contexts-resource');
|
|
|
|
parentPort.postMessage({ clientId: heldLocks[0].clientId });
|
|
|
|
await new Promise(resolve => {
|
|
parentPort.once('message', () => resolve());
|
|
});
|
|
}).catch(err => parentPort.postMessage({ error: err.message }));
|
|
`, { eval: true });
|
|
|
|
const workerResult = await new Promise((resolve) => {
|
|
worker.once('message', resolve);
|
|
});
|
|
|
|
await navigator.locks.request('different-contexts-resource', { mode: 'shared' }, async (lock) => {
|
|
const state = await navigator.locks.query();
|
|
const heldLocks = state.held.filter((l) => l.name === 'different-contexts-resource');
|
|
|
|
const mainClientId = heldLocks[0].clientId;
|
|
|
|
assert.notStrictEqual(mainClientId, workerResult.clientId);
|
|
|
|
worker.postMessage('release');
|
|
});
|
|
|
|
await worker.terminate();
|
|
});
|
|
|
|
it('should observe a deadlock scenario', async () => {
|
|
const worker = new Worker(`
|
|
const { parentPort } = require('worker_threads');
|
|
|
|
navigator.locks.request('deadlock-resource-1', async (lock1) => {
|
|
parentPort.postMessage({ acquired: 'resource1' });
|
|
|
|
await new Promise(resolve => {
|
|
parentPort.once('message', () => resolve());
|
|
});
|
|
|
|
const result = await navigator.locks.request('deadlock-resource-2',
|
|
{ ifAvailable: true }, (lock2) => lock2 !== null);
|
|
|
|
parentPort.postMessage({ acquired2: result });
|
|
|
|
await new Promise(resolve => {
|
|
parentPort.once('message', () => resolve());
|
|
});
|
|
}).catch(err => parentPort.postMessage({ error: err.message }));
|
|
`, { eval: true });
|
|
|
|
const step1 = await new Promise((resolve) => {
|
|
worker.once('message', resolve);
|
|
});
|
|
assert.strictEqual(step1.acquired, 'resource1');
|
|
|
|
await navigator.locks.request('deadlock-resource-2', async (lock2) => {
|
|
worker.postMessage('try-resource2');
|
|
|
|
const step2 = await new Promise((resolve) => {
|
|
worker.once('message', resolve);
|
|
});
|
|
assert.strictEqual(step2.acquired2, false);
|
|
|
|
const canGetResource1 = await navigator.locks.request('deadlock-resource-1',
|
|
{ ifAvailable: true }, (lock1) => lock1 !== null);
|
|
|
|
assert.strictEqual(canGetResource1, false);
|
|
|
|
const state = await navigator.locks.query();
|
|
const resource2Lock = state.held.find((l) => l.name === 'deadlock-resource-2');
|
|
assert(resource2Lock);
|
|
|
|
worker.postMessage('release');
|
|
});
|
|
|
|
await worker.terminate();
|
|
});
|
|
});
|