src: make `AsyncResource` destructor virtual

`AsyncResource` is intended to be a base class, and since we don’t
know what API consumers will do with it in their own code,
it’s good practice to make its destructor virtual.

This should not be ABI-breaking since all class methods are inline.

PR-URL: https://github.com/nodejs/node/pull/20633
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com>
Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
pull/20676/merge
Anna Henningsen 2018-05-09 18:32:59 +02:00
parent 7b39503b4a
commit 00f395db45
No known key found for this signature in database
GPG Key ID: 9C63F3A6CD2AD8F9
3 changed files with 25 additions and 1 deletions

View File

@ -712,7 +712,7 @@ class AsyncResource {
trigger_async_id);
}
~AsyncResource() {
virtual ~AsyncResource() {
EmitAsyncDestroy(isolate_, async_context_);
}

View File

@ -17,6 +17,17 @@ using v8::Object;
using v8::String;
using v8::Value;
int custom_async_resource_destructor_calls = 0;
class CustomAsyncResource : public AsyncResource {
public:
CustomAsyncResource(Isolate* isolate, Local<Object> resource)
: AsyncResource(isolate, resource, "CustomAsyncResource") {}
~CustomAsyncResource() {
custom_async_resource_destructor_calls++;
}
};
void CreateAsyncResource(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
assert(args[0]->IsObject());
@ -98,6 +109,16 @@ void GetResource(const FunctionCallbackInfo<Value>& args) {
args.GetReturnValue().Set(r->get_resource());
}
void RunSubclassTest(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
Local<Object> obj = Object::New(isolate);
assert(custom_async_resource_destructor_calls == 0);
CustomAsyncResource* resource = new CustomAsyncResource(isolate, obj);
delete static_cast<AsyncResource*>(resource);
assert(custom_async_resource_destructor_calls == 1);
}
void Initialize(Local<Object> exports) {
NODE_SET_METHOD(exports, "createAsyncResource", CreateAsyncResource);
NODE_SET_METHOD(exports, "destroyAsyncResource", DestroyAsyncResource);
@ -107,6 +128,7 @@ void Initialize(Local<Object> exports) {
NODE_SET_METHOD(exports, "getAsyncId", GetAsyncId);
NODE_SET_METHOD(exports, "getTriggerAsyncId", GetTriggerAsyncId);
NODE_SET_METHOD(exports, "getResource", GetResource);
NODE_SET_METHOD(exports, "runSubclassTest", RunSubclassTest);
}
} // anonymous namespace

View File

@ -5,6 +5,8 @@ const assert = require('assert');
const binding = require(`./build/${common.buildType}/binding`);
const async_hooks = require('async_hooks');
binding.runSubclassTest();
const kObjectTag = Symbol('kObjectTag');
const rootAsyncId = async_hooks.executionAsyncId();