Skip to content

Commit

Permalink
async_wrap: expose enable/disablePromiseHook API
Browse files Browse the repository at this point in the history
Allow node::PromiseHook (src/async-wrap.cc) to be enabled/disabled from
the JavaScript API.

PR-URL: #13509
  • Loading branch information
addaleax authored and trevnorris committed Jun 10, 2017
1 parent f533b91 commit 6a13162
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 0 deletions.
14 changes: 14 additions & 0 deletions src/async-wrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,18 @@ static void SetupHooks(const FunctionCallbackInfo<Value>& args) {
}


static void EnablePromiseHook(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
env->AddPromiseHook(PromiseHook, nullptr);
}


static void DisablePromiseHook(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
env->RemovePromiseHook(PromiseHook, nullptr);
}


void AsyncWrap::GetAsyncId(const FunctionCallbackInfo<Value>& args) {
AsyncWrap* wrap;
args.GetReturnValue().Set(-1);
Expand Down Expand Up @@ -478,6 +490,8 @@ void AsyncWrap::Initialize(Local<Object> target,
env->SetMethod(target, "popAsyncIds", PopAsyncIds);
env->SetMethod(target, "clearIdStack", ClearIdStack);
env->SetMethod(target, "addIdToDestroyList", QueueDestroyId);
env->SetMethod(target, "enablePromiseHook", EnablePromiseHook);
env->SetMethod(target, "disablePromiseHook", DisablePromiseHook);

v8::PropertyAttribute ReadOnlyDontDelete =
static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete);
Expand Down
25 changes: 25 additions & 0 deletions src/env.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#endif

#include <stdio.h>
#include <algorithm>

namespace node {

Expand Down Expand Up @@ -178,12 +179,36 @@ void Environment::AtExit(void (*cb)(void* arg), void* arg) {
}

void Environment::AddPromiseHook(promise_hook_func fn, void* arg) {
auto it = std::find_if(
promise_hooks_.begin(), promise_hooks_.end(),
[&](const PromiseHookCallback& hook) {
return hook.cb_ == fn && hook.arg_ == arg;
});
CHECK_EQ(it, promise_hooks_.end());
promise_hooks_.push_back(PromiseHookCallback{fn, arg});

if (promise_hooks_.size() == 1) {
isolate_->SetPromiseHook(EnvPromiseHook);
}
}

bool Environment::RemovePromiseHook(promise_hook_func fn, void* arg) {
auto it = std::find_if(
promise_hooks_.begin(), promise_hooks_.end(),
[&](const PromiseHookCallback& hook) {
return hook.cb_ == fn && hook.arg_ == arg;
});

if (it == promise_hooks_.end()) return false;

promise_hooks_.erase(it);
if (promise_hooks_.empty()) {
isolate_->SetPromiseHook(nullptr);
}

return true;
}

void Environment::EnvPromiseHook(v8::PromiseHookType type,
v8::Local<v8::Promise> promise,
v8::Local<v8::Value> parent) {
Expand Down
1 change: 1 addition & 0 deletions src/env.h
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,7 @@ class Environment {
static const int kContextEmbedderDataIndex = NODE_CONTEXT_EMBEDDER_DATA_INDEX;

void AddPromiseHook(promise_hook_func fn, void* arg);
bool RemovePromiseHook(promise_hook_func fn, void* arg);

private:
inline void ThrowError(v8::Local<v8::Value> (*fun)(v8::Local<v8::String>),
Expand Down

0 comments on commit 6a13162

Please sign in to comment.