diff options
author | Anna Henningsen <anna@addaleax.net> | 2019-06-19 19:24:14 -0700 |
---|---|---|
committer | Rich Trott <rtrott@gmail.com> | 2019-07-24 20:40:42 -0700 |
commit | 43e5478e2f51343b66f4d243bb4800d8e422f764 (patch) | |
tree | c2aea9ecb0b8187156fb1760da086cf356df1044 /src/node_util.cc | |
parent | 49eb2b8e2a1d964fe78d9dcf4bb1f6c7e967a931 (diff) | |
download | android-node-v8-43e5478e2f51343b66f4d243bb4800d8e422f764.tar.gz android-node-v8-43e5478e2f51343b66f4d243bb4800d8e422f764.tar.bz2 android-node-v8-43e5478e2f51343b66f4d243bb4800d8e422f764.zip |
domain: use strong reference to domain while active
When an uncaught exception is thrown inside a domain, the domain is
removed from the stack as of 43a51708589ac789ce08beaeb49d6d778dfbdc49.
This means that it might not be kept alive as an object anymore,
and may be garbage collected before the `after()` hook can run,
which tries to exit it as well.
Resolve that by making references to the domain strong while it is
active.
Fixes: https://github.com/nodejs/node/issues/28275
PR-URL: https://github.com/nodejs/node/pull/28313
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Vladimir de Turckheim <vlad2t@hotmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Diffstat (limited to 'src/node_util.cc')
-rw-r--r-- | src/node_util.cc | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/src/node_util.cc b/src/node_util.cc index 518865fe53..fa39583b04 100644 --- a/src/node_util.cc +++ b/src/node_util.cc @@ -189,12 +189,26 @@ class WeakReference : public BaseObject { args.GetReturnValue().Set(weak_ref->target_.Get(isolate)); } + static void IncRef(const FunctionCallbackInfo<Value>& args) { + WeakReference* weak_ref = Unwrap<WeakReference>(args.Holder()); + if (weak_ref->reference_count_ == 0) weak_ref->target_.ClearWeak(); + weak_ref->reference_count_++; + } + + static void DecRef(const FunctionCallbackInfo<Value>& args) { + WeakReference* weak_ref = Unwrap<WeakReference>(args.Holder()); + CHECK_GE(weak_ref->reference_count_, 1); + weak_ref->reference_count_--; + if (weak_ref->reference_count_ == 0) weak_ref->target_.SetWeak(); + } + SET_MEMORY_INFO_NAME(WeakReference) SET_SELF_SIZE(WeakReference) SET_NO_MEMORY_INFO() private: Global<Object> target_; + uint64_t reference_count_ = 0; }; static void GuessHandleType(const FunctionCallbackInfo<Value>& args) { @@ -294,6 +308,8 @@ void Initialize(Local<Object> target, weak_ref->InstanceTemplate()->SetInternalFieldCount(1); weak_ref->SetClassName(weak_ref_string); env->SetProtoMethod(weak_ref, "get", WeakReference::Get); + env->SetProtoMethod(weak_ref, "incRef", WeakReference::IncRef); + env->SetProtoMethod(weak_ref, "decRef", WeakReference::DecRef); target->Set(context, weak_ref_string, weak_ref->GetFunction(context).ToLocalChecked()).Check(); |