Skip to content

Commit b663d2b

Browse files
trevnorrisrvagg
authored andcommitted
async_wrap: call callback in destructor
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: #3461 Reviewed-By: Fedor Indutny <[email protected]>
1 parent eccbec9 commit b663d2b

File tree

6 files changed

+25
-4
lines changed

6 files changed

+25
-4
lines changed

‎src/async-wrap-inl.h‎

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,12 @@ inline AsyncWrap::AsyncWrap(Environment* env,
4141

4242
v8::Local<v8::Value> argv[] ={
4343
v8::Int32::New(env->isolate(), provider),
44+
v8::Integer::New(env->isolate(), get_uid()),
4445
Null(env->isolate())
4546
};
4647

4748
if (parent != nullptr)
48-
argv[1] = parent->object();
49+
argv[2] = parent->object();
4950

5051
v8::MaybeLocal<v8::Value> ret =
5152
init_fn->Call(env->context(), object, ARRAY_SIZE(argv), argv);
@@ -57,6 +58,22 @@ inline AsyncWrap::AsyncWrap(Environment* env,
5758
}
5859

5960

61+
inlineAsyncWrap::~AsyncWrap(){
62+
if (!ran_init_callback())
63+
return;
64+
65+
v8::Local<v8::Function> fn = env()->async_hooks_destroy_function();
66+
if (!fn.IsEmpty()){
67+
v8::HandleScope scope(env()->isolate());
68+
v8::Local<v8::Value> uid = v8::Integer::New(env()->isolate(), get_uid());
69+
v8::MaybeLocal<v8::Value> ret =
70+
fn->Call(env()->context(), v8::Null(env()->isolate()), 1, &uid);
71+
if (ret.IsEmpty())
72+
FatalError("node::AsyncWrap::~AsyncWrap", "destroy hook threw");
73+
}
74+
}
75+
76+
6077
inlineboolAsyncWrap::ran_init_callback() const{
6178
returnstatic_cast<bool>(bits_ & 1);
6279
}

‎src/async-wrap.cc‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ static void SetupHooks(const FunctionCallbackInfo<Value>& args){
131131
env->set_async_hooks_pre_function(args[1].As<Function>());
132132
if (args[2]->IsFunction())
133133
env->set_async_hooks_post_function(args[2].As<Function>());
134+
if (args[3]->IsFunction())
135+
env->set_async_hooks_destroy_function(args[3].As<Function>());
134136
}
135137

136138

@@ -156,6 +158,7 @@ static void Initialize(Local<Object> target,
156158
env->set_async_hooks_init_function(Local<Function>());
157159
env->set_async_hooks_pre_function(Local<Function>());
158160
env->set_async_hooks_post_function(Local<Function>());
161+
env->set_async_hooks_destroy_function(Local<Function>());
159162
}
160163

161164

‎src/async-wrap.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class AsyncWrap : public BaseObject{
5151
ProviderType provider,
5252
AsyncWrap* parent = nullptr);
5353

54-
inlinevirtual~AsyncWrap()override = default;
54+
inlinevirtual~AsyncWrap();
5555

5656
inline ProviderType provider_type() const;
5757

‎src/env.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ namespace node{
236236
V(async_hooks_init_function, v8::Function) \
237237
V(async_hooks_pre_function, v8::Function) \
238238
V(async_hooks_post_function, v8::Function) \
239+
V(async_hooks_destroy_function, v8::Function) \
239240
V(binding_cache_object, v8::Object) \
240241
V(buffer_constructor_function, v8::Function) \
241242
V(buffer_prototype_object, v8::Object) \

‎test/parallel/test-async-wrap-disabled-propagate-parent.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ let cntr = 0;
1010
letserver;
1111
letclient;
1212

13-
functioninit(type,parent){
13+
functioninit(type,id,parent){
1414
if(parent){
1515
cntr++;
1616
// Cannot assert in init callback or will abort.

‎test/parallel/test-async-wrap-propagate-parent.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ let cntr = 0;
99
letserver;
1010
letclient;
1111

12-
functioninit(type,parent){
12+
functioninit(type,id,parent){
1313
if(parent){
1414
cntr++;
1515
// Cannot assert in init callback or will abort.

0 commit comments

Comments
(0)