diff options
Diffstat (limited to 'src/async_wrap.cc')
-rw-r--r-- | src/async_wrap.cc | 38 |
1 files changed, 28 insertions, 10 deletions
diff --git a/src/async_wrap.cc b/src/async_wrap.cc index 58d89225e0..315d4177c8 100644 --- a/src/async_wrap.cc +++ b/src/async_wrap.cc @@ -260,8 +260,8 @@ static void PromiseHook(PromiseHookType type, Local<Promise> promise, if (wrap == nullptr) return; if (type == PromiseHookType::kBefore) { - env->async_hooks()->push_async_ids( - wrap->get_async_id(), wrap->get_trigger_async_id()); + env->async_hooks()->push_async_context(wrap->get_async_id(), + wrap->get_trigger_async_id(), wrap->object()); wrap->EmitTraceEventBefore(); AsyncWrap::EmitBefore(wrap->env(), wrap->get_async_id()); } else if (type == PromiseHookType::kAfter) { @@ -273,7 +273,7 @@ static void PromiseHook(PromiseHookType type, Local<Promise> promise, // Popping it off the stack can be skipped in that case, because it is // known that it would correspond to exactly one call with // PromiseHookType::kBefore that was not witnessed by the PromiseHook. - env->async_hooks()->pop_async_id(wrap->get_async_id()); + env->async_hooks()->pop_async_context(wrap->get_async_id()); } } else if (type == PromiseHookType::kResolve) { AsyncWrap::EmitPromiseResolve(wrap->env(), wrap->get_async_id()); @@ -382,7 +382,6 @@ static void RegisterDestroyHook(const FunctionCallbackInfo<Value>& args) { p->target.SetWeak(p, AsyncWrap::WeakCallback, WeakCallbackType::kParameter); } - void AsyncWrap::GetAsyncId(const FunctionCallbackInfo<Value>& args) { AsyncWrap* wrap; args.GetReturnValue().Set(kInvalidAsyncId); @@ -391,20 +390,20 @@ void AsyncWrap::GetAsyncId(const FunctionCallbackInfo<Value>& args) { } -void AsyncWrap::PushAsyncIds(const FunctionCallbackInfo<Value>& args) { +void AsyncWrap::PushAsyncContext(const FunctionCallbackInfo<Value>& args) { Environment* env = Environment::GetCurrent(args); // No need for CHECK(IsNumber()) on args because if FromJust() doesn't fail // then the checks in push_async_ids() and pop_async_id() will. double async_id = args[0]->NumberValue(env->context()).FromJust(); double trigger_async_id = args[1]->NumberValue(env->context()).FromJust(); - env->async_hooks()->push_async_ids(async_id, trigger_async_id); + env->async_hooks()->push_async_context(async_id, trigger_async_id, args[2]); } -void AsyncWrap::PopAsyncIds(const FunctionCallbackInfo<Value>& args) { +void AsyncWrap::PopAsyncContext(const FunctionCallbackInfo<Value>& args) { Environment* env = Environment::GetCurrent(args); double async_id = args[0]->NumberValue(env->context()).FromJust(); - args.GetReturnValue().Set(env->async_hooks()->pop_async_id(async_id)); + args.GetReturnValue().Set(env->async_hooks()->pop_async_context(async_id)); } @@ -433,6 +432,7 @@ void AsyncWrap::EmitDestroy() { AsyncWrap::EmitDestroy(env(), async_id_); // Ensure no double destroy is emitted via AsyncReset(). async_id_ = kInvalidAsyncId; + resource_.Reset(); } void AsyncWrap::QueueDestroyAsyncId(const FunctionCallbackInfo<Value>& args) { @@ -464,8 +464,8 @@ void AsyncWrap::Initialize(Local<Object> target, HandleScope scope(isolate); env->SetMethod(target, "setupHooks", SetupHooks); - env->SetMethod(target, "pushAsyncIds", PushAsyncIds); - env->SetMethod(target, "popAsyncIds", PopAsyncIds); + env->SetMethod(target, "pushAsyncContext", PushAsyncContext); + env->SetMethod(target, "popAsyncContext", PopAsyncContext); env->SetMethod(target, "queueDestroyAsyncId", QueueDestroyAsyncId); env->SetMethod(target, "enablePromiseHook", EnablePromiseHook); env->SetMethod(target, "disablePromiseHook", DisablePromiseHook); @@ -502,6 +502,10 @@ void AsyncWrap::Initialize(Local<Object> target, "async_id_fields", env->async_hooks()->async_id_fields().GetJSArray()); + FORCE_SET_TARGET_FIELD(target, + "execution_async_resources", + env->async_hooks()->execution_async_resources()); + target->Set(context, env->async_ids_stack_string(), env->async_hooks()->async_ids_stack().GetJSArray()).Check(); @@ -670,6 +674,12 @@ void AsyncWrap::AsyncReset(Local<Object> resource, double execution_async_id, : execution_async_id; trigger_async_id_ = env()->get_default_trigger_async_id(); + if (resource != object()) { + // TODO(addaleax): Using a strong reference here makes it very easy to + // introduce memory leaks. Move away from using a strong reference. + resource_.Reset(env()->isolate(), resource); + } + switch (provider_type()) { #define V(PROVIDER) \ case PROVIDER_ ## PROVIDER: \ @@ -776,6 +786,14 @@ Local<Object> AsyncWrap::GetOwner(Environment* env, Local<Object> obj) { } } +Local<Object> AsyncWrap::GetResource() { + if (resource_.IsEmpty()) { + return object(); + } + + return resource_.Get(env()->isolate()); +} + } // namespace node NODE_MODULE_CONTEXT_AWARE_INTERNAL(async_wrap, node::AsyncWrap::Initialize) |