From c5c353d98b24704e3c0555762617795c43907afa Mon Sep 17 00:00:00 2001 From: andrey filatkin Date: Tue, 12 May 2020 12:19:54 +0300 Subject: [PATCH 1/5] upgrade ObjectWrap example to multi-context support --- 6_object_wrap/node-addon-api/addon.js | 49 ++++++++++++++++++----- 6_object_wrap/node-addon-api/myobject.cc | 15 +++++-- 6_object_wrap/node-addon-api/myobject.h | 2 - 6_object_wrap/node-addon-api/package.json | 2 +- 4 files changed, 51 insertions(+), 17 deletions(-) diff --git a/6_object_wrap/node-addon-api/addon.js b/6_object_wrap/node-addon-api/addon.js index d7dd6e0a..1cb6d36e 100644 --- a/6_object_wrap/node-addon-api/addon.js +++ b/6_object_wrap/node-addon-api/addon.js @@ -1,13 +1,42 @@ -var addon = require('bindings')('addon'); +const addon = require('bindings')('addon'); +const {Worker, isMainThread, workerData} = require('worker_threads'); +const os = require('os'); -var obj = new addon.MyObject(10); -console.log( obj.plusOne() ); // 11 -console.log( obj.plusOne() ); // 12 -console.log( obj.plusOne() ); // 13 +if (isMainThread) { + (async function main() { + const threads = new Promise(resolve => { + const size = os.cpus().length * 2; + let wait = size; -console.log( obj.multiply().value() ); // 13 -console.log( obj.multiply(10).value() ); // 130 + for (let i = 0; i < size; i++) { + const worker = new Worker(__filename, {workerData: i}); -var newobj = obj.multiply(-1); -console.log( newobj.value() ); // -13 -console.log( obj === newobj ); // false + worker.on('exit', () => { + wait--; + if (wait === 0) { + resolve(); + } + }); + } + }); + + work('main'); + await threads; + })(); +} else { + work(workerData); +} + +function work(id) { + const obj = new addon.MyObject(10); + for (let i = 0; i < 10; i++) { + console.log(id, obj.plusOne()); + } + + console.log(id, obj.multiply().value()); + console.log(id, obj.multiply(10).value()); + + const newobj = obj.multiply(-1); + console.log(id, newobj.value()); + console.log(id, obj === newobj); +} diff --git a/6_object_wrap/node-addon-api/myobject.cc b/6_object_wrap/node-addon-api/myobject.cc index a81b51c7..44001833 100644 --- a/6_object_wrap/node-addon-api/myobject.cc +++ b/6_object_wrap/node-addon-api/myobject.cc @@ -1,6 +1,14 @@ #include "myobject.h" -Napi::FunctionReference MyObject::constructor; +class AddonData { +public: + AddonData(Napi::Function func) { + MyObjectConstructor = Napi::Persistent(func); + MyObjectConstructor.SuppressDestruct(); + } + + Napi::FunctionReference MyObjectConstructor; +}; Napi::Object MyObject::Init(Napi::Env env, Napi::Object exports) { Napi::HandleScope scope(env); @@ -12,8 +20,7 @@ Napi::Object MyObject::Init(Napi::Env env, Napi::Object exports) { InstanceMethod("value", &MyObject::GetValue), InstanceMethod("multiply", &MyObject::Multiply)}); - constructor = Napi::Persistent(func); - constructor.SuppressDestruct(); + env.SetInstanceData(new AddonData(func)); exports.Set("MyObject", func); return exports; @@ -55,7 +62,7 @@ Napi::Value MyObject::Multiply(const Napi::CallbackInfo& info) { multiple = info[0].As(); } - Napi::Object obj = constructor.New( + Napi::Object obj = info.Env().GetInstanceData()->MyObjectConstructor.New( {Napi::Number::New(info.Env(), this->value_ * multiple.DoubleValue())}); return obj; diff --git a/6_object_wrap/node-addon-api/myobject.h b/6_object_wrap/node-addon-api/myobject.h index fbd30588..e8ccad93 100644 --- a/6_object_wrap/node-addon-api/myobject.h +++ b/6_object_wrap/node-addon-api/myobject.h @@ -9,8 +9,6 @@ class MyObject : public Napi::ObjectWrap { MyObject(const Napi::CallbackInfo& info); private: - static Napi::FunctionReference constructor; - Napi::Value GetValue(const Napi::CallbackInfo& info); Napi::Value PlusOne(const Napi::CallbackInfo& info); Napi::Value Multiply(const Napi::CallbackInfo& info); diff --git a/6_object_wrap/node-addon-api/package.json b/6_object_wrap/node-addon-api/package.json index 37fc7045..778d4f05 100644 --- a/6_object_wrap/node-addon-api/package.json +++ b/6_object_wrap/node-addon-api/package.json @@ -7,6 +7,6 @@ "gypfile": true, "dependencies": { "bindings": "~1.2.1", - "node-addon-api": "^1.0.0" + "node-addon-api": "^3.0.0" } } From 6fdc2be7630e4a1c9fb2d0482e1e90ce036b9618 Mon Sep 17 00:00:00 2001 From: andrey filatkin Date: Tue, 12 May 2020 17:19:04 +0300 Subject: [PATCH 2/5] add node 14 constraint --- 6_object_wrap/node-addon-api/package.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/6_object_wrap/node-addon-api/package.json b/6_object_wrap/node-addon-api/package.json index 778d4f05..ad5d6671 100644 --- a/6_object_wrap/node-addon-api/package.json +++ b/6_object_wrap/node-addon-api/package.json @@ -5,6 +5,9 @@ "main": "addon.js", "private": true, "gypfile": true, + "engines": { + "node": ">= 14.0.0" + }, "dependencies": { "bindings": "~1.2.1", "node-addon-api": "^3.0.0" From 970565ded3e02d487b41b0280db42f310cebf553 Mon Sep 17 00:00:00 2001 From: andrey filatkin Date: Thu, 14 May 2020 11:21:03 +0300 Subject: [PATCH 3/5] Revert "add node 14 constraint" This reverts commit 6fdc2be7 --- 6_object_wrap/node-addon-api/package.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/6_object_wrap/node-addon-api/package.json b/6_object_wrap/node-addon-api/package.json index ad5d6671..778d4f05 100644 --- a/6_object_wrap/node-addon-api/package.json +++ b/6_object_wrap/node-addon-api/package.json @@ -5,9 +5,6 @@ "main": "addon.js", "private": true, "gypfile": true, - "engines": { - "node": ">= 14.0.0" - }, "dependencies": { "bindings": "~1.2.1", "node-addon-api": "^3.0.0" From 4b1cc90e252416f0a727df713c780faab568fc84 Mon Sep 17 00:00:00 2001 From: andrey filatkin Date: Thu, 14 May 2020 11:21:11 +0300 Subject: [PATCH 4/5] Revert "upgrade ObjectWrap example to multi-context support" This reverts commit c5c353d9 --- 6_object_wrap/node-addon-api/addon.js | 49 +++++------------------ 6_object_wrap/node-addon-api/myobject.cc | 15 ++----- 6_object_wrap/node-addon-api/myobject.h | 2 + 6_object_wrap/node-addon-api/package.json | 2 +- 4 files changed, 17 insertions(+), 51 deletions(-) diff --git a/6_object_wrap/node-addon-api/addon.js b/6_object_wrap/node-addon-api/addon.js index 1cb6d36e..d7dd6e0a 100644 --- a/6_object_wrap/node-addon-api/addon.js +++ b/6_object_wrap/node-addon-api/addon.js @@ -1,42 +1,13 @@ -const addon = require('bindings')('addon'); -const {Worker, isMainThread, workerData} = require('worker_threads'); -const os = require('os'); +var addon = require('bindings')('addon'); -if (isMainThread) { - (async function main() { - const threads = new Promise(resolve => { - const size = os.cpus().length * 2; - let wait = size; +var obj = new addon.MyObject(10); +console.log( obj.plusOne() ); // 11 +console.log( obj.plusOne() ); // 12 +console.log( obj.plusOne() ); // 13 - for (let i = 0; i < size; i++) { - const worker = new Worker(__filename, {workerData: i}); +console.log( obj.multiply().value() ); // 13 +console.log( obj.multiply(10).value() ); // 130 - worker.on('exit', () => { - wait--; - if (wait === 0) { - resolve(); - } - }); - } - }); - - work('main'); - await threads; - })(); -} else { - work(workerData); -} - -function work(id) { - const obj = new addon.MyObject(10); - for (let i = 0; i < 10; i++) { - console.log(id, obj.plusOne()); - } - - console.log(id, obj.multiply().value()); - console.log(id, obj.multiply(10).value()); - - const newobj = obj.multiply(-1); - console.log(id, newobj.value()); - console.log(id, obj === newobj); -} +var newobj = obj.multiply(-1); +console.log( newobj.value() ); // -13 +console.log( obj === newobj ); // false diff --git a/6_object_wrap/node-addon-api/myobject.cc b/6_object_wrap/node-addon-api/myobject.cc index 44001833..a81b51c7 100644 --- a/6_object_wrap/node-addon-api/myobject.cc +++ b/6_object_wrap/node-addon-api/myobject.cc @@ -1,14 +1,6 @@ #include "myobject.h" -class AddonData { -public: - AddonData(Napi::Function func) { - MyObjectConstructor = Napi::Persistent(func); - MyObjectConstructor.SuppressDestruct(); - } - - Napi::FunctionReference MyObjectConstructor; -}; +Napi::FunctionReference MyObject::constructor; Napi::Object MyObject::Init(Napi::Env env, Napi::Object exports) { Napi::HandleScope scope(env); @@ -20,7 +12,8 @@ Napi::Object MyObject::Init(Napi::Env env, Napi::Object exports) { InstanceMethod("value", &MyObject::GetValue), InstanceMethod("multiply", &MyObject::Multiply)}); - env.SetInstanceData(new AddonData(func)); + constructor = Napi::Persistent(func); + constructor.SuppressDestruct(); exports.Set("MyObject", func); return exports; @@ -62,7 +55,7 @@ Napi::Value MyObject::Multiply(const Napi::CallbackInfo& info) { multiple = info[0].As(); } - Napi::Object obj = info.Env().GetInstanceData()->MyObjectConstructor.New( + Napi::Object obj = constructor.New( {Napi::Number::New(info.Env(), this->value_ * multiple.DoubleValue())}); return obj; diff --git a/6_object_wrap/node-addon-api/myobject.h b/6_object_wrap/node-addon-api/myobject.h index e8ccad93..fbd30588 100644 --- a/6_object_wrap/node-addon-api/myobject.h +++ b/6_object_wrap/node-addon-api/myobject.h @@ -9,6 +9,8 @@ class MyObject : public Napi::ObjectWrap { MyObject(const Napi::CallbackInfo& info); private: + static Napi::FunctionReference constructor; + Napi::Value GetValue(const Napi::CallbackInfo& info); Napi::Value PlusOne(const Napi::CallbackInfo& info); Napi::Value Multiply(const Napi::CallbackInfo& info); diff --git a/6_object_wrap/node-addon-api/package.json b/6_object_wrap/node-addon-api/package.json index 778d4f05..37fc7045 100644 --- a/6_object_wrap/node-addon-api/package.json +++ b/6_object_wrap/node-addon-api/package.json @@ -7,6 +7,6 @@ "gypfile": true, "dependencies": { "bindings": "~1.2.1", - "node-addon-api": "^3.0.0" + "node-addon-api": "^1.0.0" } } From 42d19cfec6f83faf42cc75fc5b088b9f8014782c Mon Sep 17 00:00:00 2001 From: andrey filatkin Date: Thu, 14 May 2020 11:28:22 +0300 Subject: [PATCH 5/5] Add an example of ObjectWrap for multi-context --- .../node-addon-api/addon.cc | 8 +++ .../node-addon-api/addon.js | 42 +++++++++++ .../node-addon-api/binding.gyp | 14 ++++ .../node-addon-api/myobject.cc | 69 +++++++++++++++++++ .../node-addon-api/myobject.h | 19 +++++ .../node-addon-api/package.json | 15 ++++ 6 files changed, 167 insertions(+) create mode 100644 multiple_load_object_wrap/node-addon-api/addon.cc create mode 100644 multiple_load_object_wrap/node-addon-api/addon.js create mode 100644 multiple_load_object_wrap/node-addon-api/binding.gyp create mode 100644 multiple_load_object_wrap/node-addon-api/myobject.cc create mode 100644 multiple_load_object_wrap/node-addon-api/myobject.h create mode 100644 multiple_load_object_wrap/node-addon-api/package.json diff --git a/multiple_load_object_wrap/node-addon-api/addon.cc b/multiple_load_object_wrap/node-addon-api/addon.cc new file mode 100644 index 00000000..d79fbc42 --- /dev/null +++ b/multiple_load_object_wrap/node-addon-api/addon.cc @@ -0,0 +1,8 @@ +#include +#include "myobject.h" + +Napi::Object InitAll(Napi::Env env, Napi::Object exports) { + return MyObject::Init(env, exports); +} + +NODE_API_MODULE(addon, InitAll) diff --git a/multiple_load_object_wrap/node-addon-api/addon.js b/multiple_load_object_wrap/node-addon-api/addon.js new file mode 100644 index 00000000..1cb6d36e --- /dev/null +++ b/multiple_load_object_wrap/node-addon-api/addon.js @@ -0,0 +1,42 @@ +const addon = require('bindings')('addon'); +const {Worker, isMainThread, workerData} = require('worker_threads'); +const os = require('os'); + +if (isMainThread) { + (async function main() { + const threads = new Promise(resolve => { + const size = os.cpus().length * 2; + let wait = size; + + for (let i = 0; i < size; i++) { + const worker = new Worker(__filename, {workerData: i}); + + worker.on('exit', () => { + wait--; + if (wait === 0) { + resolve(); + } + }); + } + }); + + work('main'); + await threads; + })(); +} else { + work(workerData); +} + +function work(id) { + const obj = new addon.MyObject(10); + for (let i = 0; i < 10; i++) { + console.log(id, obj.plusOne()); + } + + console.log(id, obj.multiply().value()); + console.log(id, obj.multiply(10).value()); + + const newobj = obj.multiply(-1); + console.log(id, newobj.value()); + console.log(id, obj === newobj); +} diff --git a/multiple_load_object_wrap/node-addon-api/binding.gyp b/multiple_load_object_wrap/node-addon-api/binding.gyp new file mode 100644 index 00000000..85a1a2fa --- /dev/null +++ b/multiple_load_object_wrap/node-addon-api/binding.gyp @@ -0,0 +1,14 @@ +{ + "targets": [ + { + "target_name": "addon", + "cflags!": [ "-fno-exceptions" ], + "cflags_cc!": [ "-fno-exceptions" ], + "sources": [ "addon.cc", "myobject.cc" ], + "include_dirs": [ + "(info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + int length = info.Length(); + + if (length <= 0 || !info[0].IsNumber()) { + Napi::TypeError::New(env, "Number expected").ThrowAsJavaScriptException(); + return; + } + + Napi::Number value = info[0].As(); + this->value_ = value.DoubleValue(); +} + +Napi::Value MyObject::GetValue(const Napi::CallbackInfo& info) { + double num = this->value_; + + return Napi::Number::New(info.Env(), num); +} + +Napi::Value MyObject::PlusOne(const Napi::CallbackInfo& info) { + this->value_ = this->value_ + 1; + + return MyObject::GetValue(info); +} + +Napi::Value MyObject::Multiply(const Napi::CallbackInfo& info) { + Napi::Number multiple; + if (info.Length() <= 0 || !info[0].IsNumber()) { + multiple = Napi::Number::New(info.Env(), 1); + } else { + multiple = info[0].As(); + } + + Napi::Object obj = info.Env().GetInstanceData()->MyObjectConstructor.New( + {Napi::Number::New(info.Env(), this->value_ * multiple.DoubleValue())}); + + return obj; +} diff --git a/multiple_load_object_wrap/node-addon-api/myobject.h b/multiple_load_object_wrap/node-addon-api/myobject.h new file mode 100644 index 00000000..e8ccad93 --- /dev/null +++ b/multiple_load_object_wrap/node-addon-api/myobject.h @@ -0,0 +1,19 @@ +#ifndef MYOBJECT_H +#define MYOBJECT_H + +#include + +class MyObject : public Napi::ObjectWrap { + public: + static Napi::Object Init(Napi::Env env, Napi::Object exports); + MyObject(const Napi::CallbackInfo& info); + + private: + Napi::Value GetValue(const Napi::CallbackInfo& info); + Napi::Value PlusOne(const Napi::CallbackInfo& info); + Napi::Value Multiply(const Napi::CallbackInfo& info); + + double value_; +}; + +#endif diff --git a/multiple_load_object_wrap/node-addon-api/package.json b/multiple_load_object_wrap/node-addon-api/package.json new file mode 100644 index 00000000..787204ee --- /dev/null +++ b/multiple_load_object_wrap/node-addon-api/package.json @@ -0,0 +1,15 @@ +{ + "name": "object_wrap", + "version": "0.0.0", + "description": "Multiple load example of ObjectWrap", + "main": "addon.js", + "private": true, + "gypfile": true, + "engines": { + "node": ">= 14.0.0" + }, + "dependencies": { + "bindings": "~1.2.1", + "node-addon-api": "^3.0.0" + } +}