From 44532ff4465138f3e34b1ac9d1c892c8a81e90bc Mon Sep 17 00:00:00 2001 From: Gus Caplan Date: Wed, 5 Sep 2018 18:29:31 -0500 Subject: [PATCH 1/4] worker: implement web locks api --- doc/api/worker_threads.md | 104 +++++++++++++ lib/internal/worker.js | 152 ++++++++++++++++++- lib/worker_threads.js | 6 +- node.gyp | 2 + src/env.h | 5 + src/node_internals.h | 1 + src/node_locks.cc | 304 ++++++++++++++++++++++++++++++++++++++ src/node_locks.h | 117 +++++++++++++++ tools/doc/type-parser.js | 2 + 9 files changed, 690 insertions(+), 3 deletions(-) create mode 100644 src/node_locks.cc create mode 100644 src/node_locks.h diff --git a/doc/api/worker_threads.md b/doc/api/worker_threads.md index b9f28cbfbe411b..ed5f23d10e1a4f 100644 --- a/doc/api/worker_threads.md +++ b/doc/api/worker_threads.md @@ -92,6 +92,106 @@ added: v10.5.0 An arbitrary JavaScript value that contains a clone of the data passed to this thread’s `Worker` constructor. +## worker.locks + + +* {LockManager} + +An instance of a [`LockManager`][]. + +## Class: Lock + + +The Lock interface provides the name and mode of a previously requested lock, +which is received in the callback to [`LockManager.request()`][]. + +### lock.name + + +* {string} + +The name of this lock. + +### lock.mode + + +* {string} + +The mode of this lock. Either `shared` or `exclusive`. + +## Class: LockManager + + +The `LockManager` interface provides methods for requesting a new [`Lock`][] +object and querying for an existing `Lock` object. To get an instance of +`LockManager`, call `worker_threads.locks`. + +With the exception of `AbortController` support, this implementation matches +the [browser `LockManager`][] API. + +### locks.request(name[, options], callback) + + +* `name` {string} +* `options` {Object} + * `mode` {string} Either `'exclusive'` or `'shared'`. **Default:** + `'exclusive'`. + * `ifAvailable` {boolean} If `true`, the lock request will only be + granted if it is not already held. If it cannot be granted, the + callback will be invoked with `null` instead of a `Lock` instance. + **Default:** `false`. + * `steal` {boolean} If `true`, then any held locks with the same name will be + released, and the request will be granted, preempting any queued requests + for it. **Default:** `false`. +* `callback` {Function} The function to be invoked while the lock is acquired. + The lock will be released when the function ends, or if the function returns + a promise, when that promise settles. +* Returns: {Promise} + +Requests a [`Lock`][] object with parameters specifying its name and +characteristics. + +```js +worker_threads.locks.request('my_resource', async (lock) => { + // The lock was granted. +}).then(() => { + // The lock is released here. +}); +``` + +### locks.query() + + +* Returns: {Promise} + +Returns a Promise that resolves with a [`LockManagerSnapshot`][] which contains +information about held and pending locks. + +```js +worker_threads.locks.query().then((state) => { + state.held.forEach((lock) => { + console.log(`held lock: name ${lock.name}, mode ${lock.mode}`); + }); + state.pending.forEach((request) => { + console.log(`requested lock: name ${request.name}, mode ${request.mode}`); + }); +}); +``` + ## Class: MessageChannel