Call a user's callback to notify that the handle has been destroyed.
Only pass the id of the AsyncWrap instance since the object no longer
exists.
The object that's being destructed should never be inspected within the
callback or any time afterward.
This commit make a breaking change. The init callback will now be passed
arguments in the order of provider, id, parent.
PR-URL: https://github.com/nodejs/node/pull/3461
Reviewed-By: Fedor Indutny <fedor@indutny.com>
v8::Local<v8::Value> argv[] = {
v8::Int32::New(env->isolate(), provider),
+ v8::Integer::New(env->isolate(), get_uid()),
Null(env->isolate())
};
if (parent != nullptr)
- argv[1] = parent->object();
+ argv[2] = parent->object();
v8::MaybeLocal<v8::Value> ret =
init_fn->Call(env->context(), object, ARRAY_SIZE(argv), argv);
}
+inline AsyncWrap::~AsyncWrap() {
+ if (!ran_init_callback())
+ return;
+
+ v8::Local<v8::Function> fn = env()->async_hooks_destroy_function();
+ if (!fn.IsEmpty()) {
+ v8::HandleScope scope(env()->isolate());
+ v8::Local<v8::Value> uid = v8::Integer::New(env()->isolate(), get_uid());
+ v8::MaybeLocal<v8::Value> ret =
+ fn->Call(env()->context(), v8::Null(env()->isolate()), 1, &uid);
+ if (ret.IsEmpty())
+ FatalError("node::AsyncWrap::~AsyncWrap", "destroy hook threw");
+ }
+}
+
+
inline bool AsyncWrap::ran_init_callback() const {
return static_cast<bool>(bits_ & 1);
}
env->set_async_hooks_pre_function(args[1].As<Function>());
if (args[2]->IsFunction())
env->set_async_hooks_post_function(args[2].As<Function>());
+ if (args[3]->IsFunction())
+ env->set_async_hooks_destroy_function(args[3].As<Function>());
}
env->set_async_hooks_init_function(Local<Function>());
env->set_async_hooks_pre_function(Local<Function>());
env->set_async_hooks_post_function(Local<Function>());
+ env->set_async_hooks_destroy_function(Local<Function>());
}
ProviderType provider,
AsyncWrap* parent = nullptr);
- inline virtual ~AsyncWrap() override = default;
+ inline virtual ~AsyncWrap();
inline ProviderType provider_type() const;
V(async_hooks_init_function, v8::Function) \
V(async_hooks_pre_function, v8::Function) \
V(async_hooks_post_function, v8::Function) \
+ V(async_hooks_destroy_function, v8::Function) \
V(binding_cache_object, v8::Object) \
V(buffer_constructor_function, v8::Function) \
V(buffer_prototype_object, v8::Object) \
let server;
let client;
-function init(type, parent) {
+function init(type, id, parent) {
if (parent) {
cntr++;
// Cannot assert in init callback or will abort.
let server;
let client;
-function init(type, parent) {
+function init(type, id, parent) {
if (parent) {
cntr++;
// Cannot assert in init callback or will abort.