| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent f2abe7b commit 95353c7
5 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -234,6 +234,23 @@ NODE_MODULE_INIT(/* exports, module, context */) { | |||
| 234 | 234 | } | |
| 235 | 235 | ``` | |
| 236 | 236 | ||
| 237 | + #### Worker support | ||
| 238 | + | ||
| 239 | + In order to support [`Worker`][] threads, addons need to clean up any resources | ||
| 240 | + they may have allocated when such a thread exists. This can be achieved through | ||
| 241 | + the usage of the `AddEnvironmentCleanupHook()` function: | ||
| 242 | + | ||
| 243 | + ```c++ | ||
| 244 | + void AddEnvironmentCleanupHook(v8::Isolate* isolate, | ||
| 245 | + void (*fun)(void* arg), | ||
| 246 | + void* arg); | ||
| 247 | + ``` | ||
| 248 | + | ||
| 249 | + This function adds a hook that will run before a given Node.js instance shuts | ||
| 250 | + down. If necessary, such hooks can be removed using | ||
| 251 | + `RemoveEnvironmentCleanupHook()` before they are run, which has the same | ||
| 252 | + signature. | ||
| 253 | + | ||
| 237 | 254 | ### Building | |
| 238 | 255 | ||
| 239 | 256 | Once the source code has been written, it must be compiled into the binary | |
@@ -1349,6 +1366,7 @@ Test in JavaScript by running: | |||
| 1349 | 1366 | require('./build/Release/addon'); | |
| 1350 | 1367 | ``` | |
| 1351 | 1368 | ||
| 1369 | + [`Worker`]: worker_threads.html#worker_threads_class_worker | ||
| 1352 | 1370 | [Electron]: https://electronjs.org/ | |
| 1353 | 1371 | [Embedder's Guide]: https://github.com/v8/v8/wiki/Embedder's%20Guide | |
| 1354 | 1372 | [Linking to Node.js' own dependencies]: #addons_linking_to_node_js_own_dependencies | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,14 @@ | |||
| 1 | + // Flags: --experimental-worker | ||
| 2 | + 'use strict'; | ||
| 3 | + const common = require('../../common'); | ||
| 4 | + const assert = require('assert'); | ||
| 5 | + const path = require('path'); | ||
| 6 | + const { Worker } = require('worker_threads'); | ||
| 7 | + const binding = path.resolve(__dirname, `./build/${common.buildType}/binding`); | ||
| 8 | + | ||
| 9 | + const w = new Worker(` | ||
| 10 | + require('worker_threads').parentPort.postMessage( | ||
| 11 | + require(${JSON.stringify(binding)}).hello());`, { eval: true }); | ||
| 12 | + w.on('message', common.mustCall((message) => { | ||
| 13 | + assert.strictEqual(message, 'world'); | ||
| 14 | + })); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,46 @@ | |||
| 1 | + #include <assert.h> | ||
| 2 | + #include <node.h> | ||
| 3 | + #include <stdio.h> | ||
| 4 | + #include <stdlib.h> | ||
| 5 | + #include <v8.h> | ||
| 6 | + | ||
| 7 | + using v8::Context; | ||
| 8 | + using v8::HandleScope; | ||
| 9 | + using v8::Isolate; | ||
| 10 | + using v8::Local; | ||
| 11 | + using v8::Object; | ||
| 12 | + using v8::Value; | ||
| 13 | + | ||
| 14 | + size_t count = 0; | ||
| 15 | + | ||
| 16 | + struct statically_allocated { | ||
| 17 | + statically_allocated() { | ||
| 18 | + assert(count == 0); | ||
| 19 | + printf("ctor "); | ||
| 20 | + } | ||
| 21 | + ~statically_allocated() { | ||
| 22 | + assert(count == 0); | ||
| 23 | + printf("dtor"); | ||
| 24 | + } | ||
| 25 | + } var; | ||
| 26 | + | ||
| 27 | + void Dummy(void*) { | ||
| 28 | + assert(0); | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | + void Cleanup(void* str) { | ||
| 32 | + printf("%s ", static_cast<const char*>(str)); | ||
| 33 | + } | ||
| 34 | + | ||
| 35 | + void Initialize(Local<Object> exports, | ||
| 36 | + Local<Value> module, | ||
| 37 | + Local<Context> context) { | ||
| 38 | + node::AddEnvironmentCleanupHook( | ||
| 39 | + context->GetIsolate(), | ||
| 40 | + Cleanup, | ||
| 41 | + const_cast<void*>(static_cast<const void*>("cleanup"))); | ||
| 42 | + node::AddEnvironmentCleanupHook(context->GetIsolate(), Dummy, nullptr); | ||
| 43 | + node::RemoveEnvironmentCleanupHook(context->GetIsolate(), Dummy, nullptr); | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + NODE_MODULE_CONTEXT_AWARE(NODE_GYP_MODULE_NAME, Initialize) | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,9 @@ | |||
| 1 | + { | ||
| 2 | + 'targets': [ | ||
| 3 | + { | ||
| 4 | + 'target_name': 'binding', | ||
| 5 | + 'defines': [ 'V8_DEPRECATION_WARNINGS=1' ], | ||
| 6 | + 'sources': [ 'binding.cc' ] | ||
| 7 | + } | ||
| 8 | + ] | ||
| 9 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,21 @@ | |||
| 1 | + // Flags: --experimental-worker | ||
| 2 | + 'use strict'; | ||
| 3 | + const common = require('../../common'); | ||
| 4 | + const assert = require('assert'); | ||
| 5 | + const child_process = require('child_process'); | ||
| 6 | + const path = require('path'); | ||
| 7 | + const { Worker } = require('worker_threads'); | ||
| 8 | + const binding = path.resolve(__dirname, `./build/${common.buildType}/binding`); | ||
| 9 | + | ||
| 10 | + if (process.argv[2] === 'child') { | ||
| 11 | + new Worker(`require(${JSON.stringify(binding)});`, { eval: true }); | ||
| 12 | + } else { | ||
| 13 | + const proc = child_process.spawnSync(process.execPath, [ | ||
| 14 | + '--experimental-worker', | ||
| 15 | + __filename, | ||
| 16 | + 'child' | ||
| 17 | + ]); | ||
| 18 | + assert.strictEqual(proc.stderr.toString(), ''); | ||
| 19 | + assert.strictEqual(proc.stdout.toString(), 'ctor cleanup dtor'); | ||
| 20 | + assert.strictEqual(proc.status, 0); | ||
| 21 | + } | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments