Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/doc/api
diff options
context:
space:
mode:
authorGabriel Schulhof <gabriel.schulhof@intel.com>2019-07-12 20:51:00 +0300
committerGabriel Schulhof <gabriel.schulhof@intel.com>2020-03-31 20:22:12 +0300
commite158218fb23ae7cea7aa5d27ee2092a4b6d96184 (patch)
treea4749238895a3817755033fb889f630b17b44324 /doc/api
parentaccc984ca93a9d002cc61f5960fcfe5902622cb4 (diff)
doc: update context-aware section of addon doc
Replace the portion of the context-aware addon example that advocates for managing the life cycle of the per-addon-instance data using a weak reference with code that illustrates how to manage its life cycle using an environment cleanup hook. Signed-off-by: Gabriel Schulhof <gabriel.schulhof@intel.com> PR-URL: https://github.com/nodejs/node/pull/28659 Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Diffstat (limited to 'doc/api')
-rw-r--r--doc/api/addons.md61
1 files changed, 32 insertions, 29 deletions
diff --git a/doc/api/addons.md b/doc/api/addons.md
index e6b5704e8fb..ffbecb02d8f 100644
--- a/doc/api/addons.md
+++ b/doc/api/addons.md
@@ -155,18 +155,25 @@ they were created.
The context-aware addon can be structured to avoid global static data by
performing the following steps:
-
-* defining a class which will hold per-addon-instance data. Such
-a class should include a `v8::Global<v8::Object>` which will hold a weak
-reference to the addon's `exports` object. The callback associated with the weak
-reference will then destroy the instance of the class.
-* constructing an instance of this class in the addon initializer such that the
-`v8::Global<v8::Object>` is set to the `exports` object.
-* storing the instance of the class in a `v8::External`, and
-* passing the `v8::External` to all methods exposed to JavaScript by passing it
-to the `v8::FunctionTemplate` constructor which creates the native-backed
-JavaScript functions. The `v8::FunctionTemplate` constructor's third parameter
-accepts the `v8::External`.
+* Define a class which will hold per-addon-instance data and which has a static
+member of the form
+ ```C++
+ static void DeleteInstance(void* data) {
+ // Cast `data` to an instance of the class and delete it.
+ }
+ ```
+* Heap-allocate an instance of this class in the addon initializer. This can be
+accomplished using the `new` keyword.
+* Call `node::AddEnvironmentCleanupHook()`, passing it the above-created
+instance and a pointer to `DeleteInstance()`. This will ensure the instance is
+deleted when the environment is torn down.
+* Store the instance of the class in a `v8::External`, and
+* Pass the `v8::External` to all methods exposed to JavaScript by passing it
+to `v8::FunctionTemplate::New()` or `v8::Function::New()` which creates the
+native-backed JavaScript functions. The third parameter of
+`v8::FunctionTemplate::New()` or `v8::Function::New()` accepts the
+`v8::External` and makes it available in the native callback using the
+`v8::FunctionCallbackInfo::Data()` method.
This will ensure that the per-addon-instance data reaches each binding that can
be called from JavaScript. The per-addon-instance data must also be passed into
@@ -181,25 +188,18 @@ using namespace v8;
class AddonData {
public:
- AddonData(Isolate* isolate, Local<Object> exports):
+ explicit AddonData(Isolate* isolate):
call_count(0) {
- // Link the existence of this object instance to the existence of exports.
- exports_.Reset(isolate, exports);
- exports_.SetWeak(this, DeleteMe, WeakCallbackType::kParameter);
+ // Ensure this per-addon-instance data is deleted at environment cleanup.
+ node::AddEnvironmentCleanupHook(isolate, DeleteInstance, this);
}
// Per-addon data.
int call_count;
- private:
- // Method to call when "exports" is about to be garbage-collected.
- static void DeleteMe(const WeakCallbackInfo<AddonData>& info) {
- delete info.GetParameter();
+ static void DeleteInstance(void* data) {
+ delete static_cast<AddonData*>(data);
}
-
- // Weak handle to the "exports" object. An instance of this class will be
- // destroyed along with the exports object to which it is weakly bound.
- v8::Global<v8::Object> exports_;
};
static void Method(const v8::FunctionCallbackInfo<v8::Value>& info) {
@@ -214,14 +214,17 @@ static void Method(const v8::FunctionCallbackInfo<v8::Value>& info) {
NODE_MODULE_INIT(/* exports, module, context */) {
Isolate* isolate = context->GetIsolate();
- // Create a new instance of AddonData for this instance of the addon.
- AddonData* data = new AddonData(isolate, exports);
- // Wrap the data in a v8::External so we can pass it to the method we expose.
+ // Create a new instance of `AddonData` for this instance of the addon and
+ // tie its life cycle to that of the Node.js environment.
+ AddonData* data = new AddonData(isolate);
+
+ // Wrap the data in a `v8::External` so we can pass it to the method we
+ // expose.
Local<External> external = External::New(isolate, data);
- // Expose the method "Method" to JavaScript, and make sure it receives the
+ // Expose the method `Method` to JavaScript, and make sure it receives the
// per-addon-instance data we created above by passing `external` as the
- // third parameter to the FunctionTemplate constructor.
+ // third parameter to the `FunctionTemplate` constructor.
exports->Set(context,
String::NewFromUtf8(isolate, "method", NewStringType::kNormal)
.ToLocalChecked(),