Skip to content

Commit

Permalink
net: make net.BlockList cloneable
Browse files Browse the repository at this point in the history
Signed-off-by: James M Snell <jasnell@gmail.com>

PR-URL: #37917
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
  • Loading branch information
jasnell authored and BethGriggs committed Aug 12, 2021
1 parent f534d7a commit cf04389
Show file tree
Hide file tree
Showing 9 changed files with 254 additions and 57 deletions.
11 changes: 8 additions & 3 deletions doc/api/worker_threads.md
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,9 @@ are part of the channel.
<!-- YAML
added: v10.5.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/37917
description: Add 'BlockList' to the list of cloneable types.
- version: v14.5.0
pr-url: https://github.com/nodejs/node/pull/33360
description: Added `KeyObject` to the list of cloneable types.
Expand All @@ -401,8 +404,11 @@ In particular, the significant differences to `JSON` are:
* `value` may contain typed arrays, both using `ArrayBuffer`s
and `SharedArrayBuffer`s.
* `value` may contain [`WebAssembly.Module`][] instances.
* `value` may not contain native (C++-backed) objects other than `MessagePort`s,
[`FileHandle`][]s, and [`KeyObject`][]s.
* `value` may not contain native (C++-backed) objects other than:
* {FileHandle}s,
* {KeyObject}s,
* {MessagePort}s,
* {net.BlockList}s,

```js
const { MessageChannel } = require('worker_threads');
Expand Down Expand Up @@ -1032,7 +1038,6 @@ thread spawned will spawn another until the application crashes.
[`ERR_WORKER_NOT_RUNNING`]: errors.md#ERR_WORKER_NOT_RUNNING
[`EventTarget`]: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget
[`FileHandle`]: fs.md#fs_class_filehandle
[`KeyObject`]: crypto.md#crypto_class_keyobject
[`MessagePort`]: #worker_threads_class_messageport
[`SharedArrayBuffer`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer
[`Uint8Array`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array
Expand Down
50 changes: 41 additions & 9 deletions lib/internal/blocklist.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

const {
Boolean,
ObjectSetPrototypeOf,
Symbol
} = primordials;

Expand All @@ -14,6 +15,13 @@ const {
const {
customInspectSymbol: kInspect,
} = require('internal/util');

const {
JSTransferable,
kClone,
kDeserialize,
} = require('internal/worker/js_transferable');

const { inspect } = require('internal/util/inspect');

const kHandle = Symbol('kHandle');
Expand All @@ -26,14 +34,10 @@ const {

const { validateInt32 } = require('internal/validators');

class BlockList {
constructor(handle = new BlockListHandle()) {
// The handle argument is an intentionally undocumented
// internal API. User code will not be able to create
// a BlockListHandle object directly.
if (!(handle instanceof BlockListHandle))
throw new ERR_INVALID_ARG_TYPE('handle', 'BlockListHandle', handle);
this[kHandle] = handle;
class BlockList extends JSTransferable {
constructor() {
super();
this[kHandle] = new BlockListHandle();
this[kHandle][owner_symbol] = this;
}

Expand Down Expand Up @@ -116,6 +120,34 @@ class BlockList {
get rules() {
return this[kHandle].getRules();
}

[kClone]() {
const handle = this[kHandle];
return {
data: { handle },
deserializeInfo: 'internal/blocklist:InternalBlockList',
};
}

[kDeserialize]({ handle }) {
this[kHandle] = handle;
this[kHandle][owner_symbol] = this;
}
}

class InternalBlockList extends JSTransferable {
constructor(handle) {
super();
this[kHandle] = handle;
if (handle !== undefined)
handle[owner_symbol] = this;
}
}

module.exports = BlockList;
InternalBlockList.prototype.constructor = BlockList.prototype.constructor;
ObjectSetPrototypeOf(InternalBlockList.prototype, BlockList.prototype);

module.exports = {
BlockList,
InternalBlockList,
};
3 changes: 1 addition & 2 deletions lib/net.js
Original file line number Diff line number Diff line change
Expand Up @@ -1757,8 +1757,7 @@ module.exports = {
_normalizeArgs: normalizeArgs,
_setSimultaneousAccepts,
get BlockList() {
if (BlockList === undefined)
BlockList = require('internal/blocklist');
BlockList = BlockList ?? require('internal/blocklist').BlockList;
return BlockList;
},
connect,
Expand Down
11 changes: 7 additions & 4 deletions src/env-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1110,15 +1110,18 @@ inline void Environment::SetInstanceMethod(v8::Local<v8::FunctionTemplate> that,
inline void Environment::SetConstructorFunction(
v8::Local<v8::Object> that,
const char* name,
v8::Local<v8::FunctionTemplate> tmpl) {
SetConstructorFunction(that, OneByteString(isolate(), name), tmpl);
v8::Local<v8::FunctionTemplate> tmpl,
SetConstructorFunctionFlag flag) {
SetConstructorFunction(that, OneByteString(isolate(), name), tmpl, flag);
}

inline void Environment::SetConstructorFunction(
v8::Local<v8::Object> that,
v8::Local<v8::String> name,
v8::Local<v8::FunctionTemplate> tmpl) {
tmpl->SetClassName(name);
v8::Local<v8::FunctionTemplate> tmpl,
SetConstructorFunctionFlag flag) {
if (LIKELY(flag == SetConstructorFunctionFlag::SET_CLASS_NAME))
tmpl->SetClassName(name);
that->Set(
context(),
name,
Expand Down
15 changes: 12 additions & 3 deletions src/env.h
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ constexpr size_t kFsStatsBufferLength =
V(async_wrap_object_ctor_template, v8::FunctionTemplate) \
V(base_object_ctor_template, v8::FunctionTemplate) \
V(binding_data_ctor_template, v8::FunctionTemplate) \
V(blocklist_instance_template, v8::ObjectTemplate) \
V(blocklist_constructor_template, v8::FunctionTemplate) \
V(compiled_fn_entry_template, v8::ObjectTemplate) \
V(dir_instance_template, v8::ObjectTemplate) \
V(fd_constructor_template, v8::ObjectTemplate) \
Expand Down Expand Up @@ -1111,13 +1111,22 @@ class Environment : public MemoryRetainer {
const char* name,
v8::FunctionCallback callback);

enum class SetConstructorFunctionFlag {
NONE,
SET_CLASS_NAME,
};

inline void SetConstructorFunction(v8::Local<v8::Object> that,
const char* name,
v8::Local<v8::FunctionTemplate> tmpl);
v8::Local<v8::FunctionTemplate> tmpl,
SetConstructorFunctionFlag flag =
SetConstructorFunctionFlag::SET_CLASS_NAME);

inline void SetConstructorFunction(v8::Local<v8::Object> that,
v8::Local<v8::String> name,
v8::Local<v8::FunctionTemplate> tmpl);
v8::Local<v8::FunctionTemplate> tmpl,
SetConstructorFunctionFlag flag =
SetConstructorFunctionFlag::SET_CLASS_NAME);

void AtExit(void (*cb)(void* arg), void* arg);
void RunAtExitCallbacks();
Expand Down
Loading

0 comments on commit cf04389

Please sign in to comment.