node-api: add napi_create_external_sharedarraybuffer#62623
node-api: add napi_create_external_sharedarraybuffer#62623bnoordhuis wants to merge 5 commits intonodejs:mainfrom
Conversation
Creates a SharedArrayBuffer from externally managed memory. Fixes: nodejs#62259
|
Review requested:
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #62623 +/- ##
==========================================
+ Coverage 89.77% 89.78% +0.01%
==========================================
Files 697 697
Lines 215749 215775 +26
Branches 41304 41295 -9
==========================================
+ Hits 193681 193740 +59
+ Misses 14161 14121 -40
- Partials 7907 7914 +7
🚀 New features to boost your workflow:
|
| node_api_basic_finalize finalize_cb, | ||
| void* finalize_hint, | ||
| napi_value* result); | ||
| NAPI_EXTERN napi_status NAPI_CDECL napi_create_external_sharedarraybuffer( |
There was a problem hiding this comment.
This should be an experimental API first.
| NAPI_EXTERN napi_status NAPI_CDECL napi_create_external_sharedarraybuffer( | |
| #ifdef NAPI_EXPERIMENTAL | |
| #define NODE_API_EXPERIMENTAL_HAS_CREATE_EXTERNAL_SHAREDARRAYBUFFER | |
| NAPI_EXTERN napi_status NAPI_CDECL napi_create_external_sharedarraybuffer( |
There was a problem hiding this comment.
Shouldn't the macro be NODE_API_EXPERIMENTAL_HAS_CREATE_EXTERNAL_SHAREDARRAYBUFFER?
| global.gc(); | ||
| await tick(10); | ||
| console.log('gc3'); | ||
| assert.strictEqual(binding.getDeleterCallCount(), 3); |
There was a problem hiding this comment.
Can we use const { gcUntil } = require('../../common/gc')? It would be more stable in tests on GC..
There was a problem hiding this comment.
This is what other parts of the test file already do. You want me to update it in its entirety?
There was a problem hiding this comment.
I think it would be helpful. But non-blocking.
|
|
||
| <!-- YAML | ||
| added: REPLACEME | ||
| napiVersion: 1 |
There was a problem hiding this comment.
This would be an experimental API first.
| napiVersion: 1 |
| Create a `SharedArrayBuffer` with externally managed memory. | ||
|
|
||
| See the entry on [`napi_create_external_arraybuffer`][] for runtime | ||
| compatibility. |
There was a problem hiding this comment.
I think a difference worth pointing out here is that the finalizer in napi_create_external_arraybuffer will be invoked on the JS thread. But this finalize_cb could be invoked on an arbitrary thread.
| node_api_basic_finalize finalize_cb, | ||
| void* finalize_hint, | ||
| napi_value* result); | ||
| NAPI_EXTERN napi_status NAPI_CDECL napi_create_external_sharedarraybuffer( |
There was a problem hiding this comment.
New Node-API functions should be prefixed with node_api_ and not napi_.
There was a problem hiding this comment.
What is the logic here? napi_create_external_arraybuffer for example is called, well, napi_create_external_arraybuffer.
| void (*finalize_cb)(void* external_data, void* finalize_hint), | ||
| void* finalize_hint, | ||
| napi_value* result) { | ||
| return v8impl::NewExternalSharedArrayBuffer( |
There was a problem hiding this comment.
Should this return napi_no_external_buffers_allowed if external buffers are not allowed, eg. when running in a sandboxed environment? Like napi_create_external_buffer does if V8_SANDBOX macro is defined.
| JavaScript `ArrayBuffer`s are described in | ||
| [Section ArrayBuffer objects][] of the ECMAScript Language Specification. | ||
|
|
||
| #### `napi_create_external_sharedarraybuffer` |
There was a problem hiding this comment.
Please use the node_api_ prefix for all node Node-API functions instead of napi_.
| napi_env env, | ||
| void* external_data, | ||
| size_t byte_length, | ||
| void (*finalize_cb)(void* external_data, void* finalize_hint), |
There was a problem hiding this comment.
We typically do not use the inline function pointer types.
Can we use the node_api_basic_finalize here?
I guess it should OK to document there that env is null there.
There was a problem hiding this comment.
I did that intentionally, of course. Passing nullptr is just setting up users for segfaults.
There was a problem hiding this comment.
I think the semantic of this finalizer is different from node_api_basic_finalize. node_api_basic_finalize is still invoked on the JS thread. But this finalizer could be invoked on non-main-JS thread. I think it is worth a dedicated type.
| return status; | ||
| } | ||
|
|
||
| napi_status NewExternalSharedArrayBuffer( |
There was a problem hiding this comment.
Can we move this implementation directly into the node_api_create_external_sharedarraybuffer. This is the pattern we use for all other Node-API functions. In practice it avoids having extra frame in the call stack when we debug code and unnecessary redirection.
There was a problem hiding this comment.
Sure, but I'm merely copying a pattern that's used elsewhere in this file. Seems a little inconsistent?
| auto shared_backing_store = | ||
| std::shared_ptr<v8::BackingStore>(std::move(unique_backing_store)); | ||
| auto shared_array_buffer = | ||
| v8::SharedArrayBuffer::New(env->isolate, shared_backing_store); |
There was a problem hiding this comment.
Please add std::move for the shared_backing_store to avoid extra ref counter interlocked increment and decrement.
| return status; | ||
| } | ||
|
|
||
| napi_status NewExternalSharedArrayBuffer( |
There was a problem hiding this comment.
Please make sure that the node_api_create_external_sharedarraybuffer has the typical set of parameter checks as we do for other Node-API functions.
| if (finalize_cb != nullptr) { | ||
| deleter_data = new FinalizerData{finalize_cb, finalize_hint}; | ||
| } | ||
| auto unique_backing_store = v8::SharedArrayBuffer::NewBackingStore( |
There was a problem hiding this comment.
It is better to avoid auto for readability when possible.
IMHO, we should only use it for lambdas and iterators.
In other trivial cases like here using the real types can help readability and see the issues sooner like with the missing std::move below.
There was a problem hiding this comment.
The counterargument is that repeating oneself at the left- and right-hand side of an assignment often results in unwieldy line noise. auto is also used quite a bit elsewhere in this file, and not just for lambdas.
For the record: I'm pretty much the founder of Node's C++ house style and I've always been a-okay with judicious use of auto.
There was a problem hiding this comment.
I think it is okay to use auto when the type is clear: https://github.com/nodejs/node/blob/main/doc/contributing/cpp-style-guide.md#using-auto
I would find this auto good because the right hand side is clear that this is a v8 backing store.
Creates a SharedArrayBuffer from externally managed memory.
Fixes: #62259