Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5d52680

Browse files
committed
worker: add web locks api
1 parent 5f7dbf4 commit 5d52680

File tree

70 files changed

+4612
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+4612
-0
lines changed

doc/api/globals.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,55 @@ consisting of the runtime name and major version number.
844844
console.log(`The user-agent is ${navigator.userAgent}`); // Prints "Node.js/21"
845845
```
846846

847+
### `navigator.locks`
848+
849+
<!-- YAML
850+
added: REPLACEME
851+
-->
852+
853+
> Stability: 1 - Experimental
854+
855+
The `navigator.locks` read-only property returns a [`LockManager`][] instance that
856+
can be used to coordinate access to resources that may be shared across multiple
857+
threads within the same process. This global implementation matches the semantics
858+
of the [browser `LockManager`][] API.
859+
860+
```mjs
861+
// Request an exclusive lock
862+
await navigator.locks.request('my_resource', async (lock) => {
863+
// The lock has been acquired.
864+
console.log(`Lock acquired: ${lock.name}`);
865+
// Lock is automatically released when the function returns
866+
});
867+
868+
// Request a shared lock
869+
await navigator.locks.request('shared_resource', { mode: 'shared' }, async (lock) => {
870+
// Multiple shared locks can be held simultaneously
871+
console.log(`Shared lock acquired: ${lock.name}`);
872+
});
873+
```
874+
875+
```cjs
876+
// Request an exclusive lock
877+
navigator.locks.request('my_resource', async (lock) => {
878+
// The lock has been acquired.
879+
console.log(`Lock acquired: ${lock.name}`);
880+
// Lock is automatically released when the function returns
881+
}).then(() => {
882+
console.log('Lock released');
883+
});
884+
885+
// Request a shared lock
886+
navigator.locks.request('shared_resource', { mode: 'shared' }, async (lock) => {
887+
// Multiple shared locks can be held simultaneously
888+
console.log(`Shared lock acquired: ${lock.name}`);
889+
}).then(() => {
890+
console.log('Shared lock released');
891+
});
892+
```
893+
894+
See [`worker.locks`][] for detailed API documentation.
895+
847896
## `PerformanceEntry`
848897

849898
<!-- YAML
@@ -1428,6 +1477,7 @@ A browser-compatible implementation of [`WritableStreamDefaultWriter`][].
14281477
[`DecompressionStream`]: webstreams.md#class-decompressionstream
14291478
[`EventSource`]: https://developer.mozilla.org/en-US/docs/Web/API/EventSource
14301479
[`EventTarget` and `Event` API]: events.md#eventtarget-and-event-api
1480+
[`LockManager`]: worker_threads.md#class-lockmanager
14311481
[`MessageChannel`]: worker_threads.md#class-messagechannel
14321482
[`MessageEvent`]: https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent/MessageEvent
14331483
[`MessagePort`]: worker_threads.md#class-messageport
@@ -1481,6 +1531,8 @@ A browser-compatible implementation of [`WritableStreamDefaultWriter`][].
14811531
[`setTimeout`]: timers.md#settimeoutcallback-delay-args
14821532
[`structuredClone`]: https://developer.mozilla.org/en-US/docs/Web/API/structuredClone
14831533
[`window.navigator`]: https://developer.mozilla.org/en-US/docs/Web/API/Window/navigator
1534+
[`worker.locks`]: worker_threads.md#workerlocks
1535+
[browser `LockManager`]: https://developer.mozilla.org/en-US/docs/Web/API/LockManager
14841536
[buffer section]: buffer.md
14851537
[built-in objects]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects
14861538
[timers]: timers.md

doc/api/worker_threads.md

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,143 @@ if (isMainThread) {
755755
}
756756
```
757757
758+
## `worker.locks`
759+
760+
<!-- YAML
761+
added: REPLACEME
762+
-->
763+
764+
> Stability: 1 - Experimental
765+
766+
* {LockManager}
767+
768+
An instance of a [`LockManager`][LockManager] that can be used to coordinate
769+
access to resources that may be shared across multiple threads within the same
770+
process. The API mirrors the semantics of the
771+
[browser `LockManager`][]
772+
773+
### Class: `Lock`
774+
775+
<!-- YAML
776+
added: REPLACEME
777+
-->
778+
779+
The `Lock` interface provides information about a lock that has been granted via
780+
[`locks.request()`][locks.request()]
781+
782+
#### `lock.name`
783+
784+
<!-- YAML
785+
added: REPLACEME
786+
-->
787+
788+
* {string}
789+
790+
The name of the lock.
791+
792+
#### `lock.mode`
793+
794+
<!-- YAML
795+
added: REPLACEME
796+
-->
797+
798+
* {string}
799+
800+
The mode of the lock. Either `shared` or `exclusive`.
801+
802+
### Class: `LockManager`
803+
804+
<!-- YAML
805+
added: REPLACEME
806+
-->
807+
808+
The `LockManager` interface provides methods for requesting and introspecting
809+
locks. To obtain a `LockManager` instance use `require('node:worker_threads').locks`.
810+
811+
This implementation matches the [browser `LockManager`][] API.
812+
813+
#### `locks.request(name[, options], callback)`
814+
815+
<!-- YAML
816+
added: REPLACEME
817+
-->
818+
819+
* `name` {string}
820+
* `options` {Object}
821+
* `mode` {string} Either `'exclusive'` or `'shared'`. **Default:** `'exclusive'`.
822+
* `ifAvailable` {boolean} If `true`, the request will only be granted if the
823+
lock is not already held. If it cannot be granted, `callback` will be
824+
invoked with `null` instead of a `Lock` instance. **Default:** `false`.
825+
* `steal` {boolean} If `true`, any existing locks with the same name are
826+
released and the request is granted immediately, pre-empting any queued
827+
requests. **Default:** `false`.
828+
* `signal` {AbortSignal} that can be used to abort a
829+
pending (but not yet granted) lock request.
830+
* `callback` {Function} Invoked once the lock is granted (or immediately with
831+
`null` if `ifAvailable` is `true` and the lock is unavailable). The lock is
832+
released automatically when the function returns, or—if the function returns
833+
a promise—when that promise settles.
834+
* Returns: {Promise} Resolves once the lock has been released.
835+
836+
```mjs
837+
import { locks } from 'node:worker_threads';
838+
839+
await locks.request('my_resource', async (lock) => {
840+
// The lock has been acquired.
841+
});
842+
// The lock has been released here.
843+
```
844+
845+
```cjs
846+
'use strict';
847+
848+
const { locks } = require('node:worker_threads');
849+
850+
locks.request('my_resource', async (lock) => {
851+
// The lock has been acquired.
852+
}).then(() => {
853+
// The lock has been released here.
854+
});
855+
```
856+
857+
#### `locks.query()`
858+
859+
<!-- YAML
860+
added: REPLACEME
861+
-->
862+
863+
* Returns: {Promise}
864+
865+
Resolves with a `LockManagerSnapshot` describing the currently held and pending
866+
locks for the current process.
867+
868+
```mjs
869+
import { locks } from 'node:worker_threads';
870+
871+
const snapshot = await locks.query();
872+
for (const lock of snapshot.held) {
873+
console.log(`held lock: name ${lock.name}, mode ${lock.mode}`);
874+
}
875+
for (const pending of snapshot.pending) {
876+
console.log(`pending lock: name ${pending.name}, mode ${pending.mode}`);
877+
}
878+
```
879+
880+
```cjs
881+
'use strict';
882+
883+
const { locks } = require('node:worker_threads');
884+
885+
locks.query().then((snapshot) => {
886+
for (const lock of snapshot.held) {
887+
console.log(`held lock: name ${lock.name}, mode ${lock.mode}`);
888+
}
889+
for (const pending of snapshot.pending) {
890+
console.log(`pending lock: name ${pending.name}, mode ${pending.mode}`);
891+
}
892+
});
893+
```
894+
758895
## Class: `BroadcastChannel extends EventTarget`
759896
760897
<!-- YAML
@@ -1935,6 +2072,7 @@ thread spawned will spawn another until the application crashes.
19352072
[Addons worker support]: addons.md#worker-support
19362073
[ECMAScript module loader]: esm.md#data-imports
19372074
[HTML structured clone algorithm]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm
2075+
[LockManager]: #class-lockmanager
19382076
[Signals events]: process.md#signal-events
19392077
[Web Workers]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API
19402078
[`'close'` event]: #event-close
@@ -1990,7 +2128,9 @@ thread spawned will spawn another until the application crashes.
19902128
[`worker.terminate()`]: #workerterminate
19912129
[`worker.threadId`]: #workerthreadid_1
19922130
[async-resource-worker-pool]: async_context.md#using-asyncresource-for-a-worker-thread-pool
2131+
[browser `LockManager`]: https://developer.mozilla.org/en-US/docs/Web/API/LockManager
19932132
[browser `MessagePort`]: https://developer.mozilla.org/en-US/docs/Web/API/MessagePort
19942133
[child processes]: child_process.md
19952134
[contextified]: vm.md#what-does-it-mean-to-contextify-an-object
2135+
[locks.request()]: #locksrequestname-options-callback
19962136
[v8.serdes]: v8.md#serialization-api

lib/internal/bootstrap/web/exposed-window-or-worker.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,6 @@ if (internalBinding('config').hasOpenSSL) {
127127
},
128128
}, 'crypto') });
129129
}
130+
131+
// https://w3c.github.io/web-locks/
132+
exposeLazyInterfaces(globalThis, 'internal/locks', ['LockManager', 'Lock']);

0 commit comments

Comments
 (0)