summaryrefslogtreecommitdiff
path: root/src/node_util.cc
diff options
context:
space:
mode:
authorAnna Henningsen <anna@addaleax.net>2019-06-19 19:24:14 -0700
committerRich Trott <rtrott@gmail.com>2019-07-24 20:40:42 -0700
commit43e5478e2f51343b66f4d243bb4800d8e422f764 (patch)
treec2aea9ecb0b8187156fb1760da086cf356df1044 /src/node_util.cc
parent49eb2b8e2a1d964fe78d9dcf4bb1f6c7e967a931 (diff)
downloadandroid-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.cc16
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();