mirror of
https://github.com/nodejs/node.git
synced 2024-12-01 16:10:02 +01:00
doc: add warnings about transferring Buffers and ArrayBuffer
Signed-off-by: James M Snell <jasnell@gmail.com> PR-URL: https://github.com/nodejs/node/pull/33252 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Mathias Buus <mathiasbuus@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
This commit is contained in:
parent
e454e9b33f
commit
baba42c38b
@ -396,6 +396,51 @@ posting without having side effects.
|
||||
For more information on the serialization and deserialization mechanisms
|
||||
behind this API, see the [serialization API of the `v8` module][v8.serdes].
|
||||
|
||||
#### Considerations when transferring TypedArrays and Buffers
|
||||
|
||||
All `TypedArray` and `Buffer` instances are views over an underlying
|
||||
`ArrayBuffer`. That is, it is the `ArrayBuffer` that actually stores
|
||||
the raw data while the `TypedArray` and `Buffer` objects provide a
|
||||
way of viewing and manipulating the data. It is possible and common
|
||||
for multiple views to be created over the same `ArrayBuffer` instance.
|
||||
Great care must be taken when using a transfer list to transfer an
|
||||
`ArrayBuffer` as doing so will cause all `TypedArray` and `Buffer`
|
||||
instances that share that same `ArrayBuffer` to become unusable.
|
||||
|
||||
```js
|
||||
const ab = new ArrayBuffer(10);
|
||||
|
||||
const u1 = new Uint8Array(ab);
|
||||
const u2 = new Uint16Array(ab);
|
||||
|
||||
console.log(u2.length); // prints 5
|
||||
|
||||
port.postMessage(u1, [u1.buffer]);
|
||||
|
||||
console.log(u2.length); // prints 0
|
||||
```
|
||||
|
||||
For `Buffer` instances, specifically, whether the underlying
|
||||
`ArrayBuffer` can be transferred or cloned depends entirely on how
|
||||
instances were created, which often cannot be reliably determined.
|
||||
|
||||
Depending on how a `Buffer` instance was created, it may or may
|
||||
not own its underlying `ArrayBuffer`. An `ArrayBuffer` must not
|
||||
be transferred unless it is known that the `Buffer` instance
|
||||
owns it. In particular, for `Buffer`s created from the internal
|
||||
`Buffer` pool (using, for instance `Buffer.from()` or `Buffer.alloc()`),
|
||||
transferring them is not possible and they will always be cloned,
|
||||
which sends a copy of the entire `Buffer` pool.
|
||||
This behavior may come with unintended higher memory
|
||||
usage and possible security concerns.
|
||||
|
||||
See [`Buffer.allocUnsafe()`][] for more details on `Buffer` pooling.
|
||||
|
||||
The `ArrayBuffer`s for `Buffer` instances created using
|
||||
`Buffer.alloc()` or `Buffer.allocUnsafeSlow()` can always be
|
||||
transferred but doing so will render all other existing views of
|
||||
those `ArrayBuffer`s unusable.
|
||||
|
||||
### `port.ref()`
|
||||
<!-- YAML
|
||||
added: v10.5.0
|
||||
@ -767,6 +812,7 @@ active handle in the event system. If the worker is already `unref()`ed calling
|
||||
[`'exit'` event]: #worker_threads_event_exit
|
||||
[`AsyncResource`]: async_hooks.html#async_hooks_class_asyncresource
|
||||
[`Buffer`]: buffer.html
|
||||
[`Buffer.allocUnsafe()`]: buffer.html#buffer_class_method_buffer_allocunsafe_size
|
||||
[`ERR_MISSING_MESSAGE_PORT_IN_TRANSFER_LIST`]: errors.html#errors_err_missing_message_port_in_transfer_list
|
||||
[`ERR_WORKER_NOT_RUNNING`]: errors.html#ERR_WORKER_NOT_RUNNING
|
||||
[`EventEmitter`]: events.html
|
||||
|
Loading…
Reference in New Issue
Block a user