Skip to content

Commit 96279e8

Browse files
committed
async_wrap: expose enable/disablePromiseHook API
Allow node::PromiseHook (src/async-wrap.cc) to be enabled/disabled from the JavaScript API. PR-URL: #13509 Reviewed-By: Andreas Madsen <[email protected]> Reviewed-By: Anna Henningsen <[email protected]>
1 parent 8b57b09 commit 96279e8

File tree

3 files changed

+40
-0
lines changed

3 files changed

+40
-0
lines changed

src/async-wrap.cc

+14
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,18 @@ static void SetupHooks(const FunctionCallbackInfo<Value>& args) {
422422
}
423423

424424

425+
static void EnablePromiseHook(const FunctionCallbackInfo<Value>& args) {
426+
Environment* env = Environment::GetCurrent(args);
427+
env->AddPromiseHook(PromiseHook, nullptr);
428+
}
429+
430+
431+
static void DisablePromiseHook(const FunctionCallbackInfo<Value>& args) {
432+
Environment* env = Environment::GetCurrent(args);
433+
env->RemovePromiseHook(PromiseHook, nullptr);
434+
}
435+
436+
425437
void AsyncWrap::GetAsyncId(const FunctionCallbackInfo<Value>& args) {
426438
AsyncWrap* wrap;
427439
args.GetReturnValue().Set(-1);
@@ -478,6 +490,8 @@ void AsyncWrap::Initialize(Local<Object> target,
478490
env->SetMethod(target, "popAsyncIds", PopAsyncIds);
479491
env->SetMethod(target, "clearIdStack", ClearIdStack);
480492
env->SetMethod(target, "addIdToDestroyList", QueueDestroyId);
493+
env->SetMethod(target, "enablePromiseHook", EnablePromiseHook);
494+
env->SetMethod(target, "disablePromiseHook", DisablePromiseHook);
481495

482496
v8::PropertyAttribute ReadOnlyDontDelete =
483497
static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete);

src/env.cc

+25
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#endif
1212

1313
#include <stdio.h>
14+
#include <algorithm>
1415

1516
namespace node {
1617

@@ -178,12 +179,36 @@ void Environment::AtExit(void (*cb)(void* arg), void* arg) {
178179
}
179180

180181
void Environment::AddPromiseHook(promise_hook_func fn, void* arg) {
182+
auto it = std::find_if(
183+
promise_hooks_.begin(), promise_hooks_.end(),
184+
[&](const PromiseHookCallback& hook) {
185+
return hook.cb_ == fn && hook.arg_ == arg;
186+
});
187+
CHECK_EQ(it, promise_hooks_.end());
181188
promise_hooks_.push_back(PromiseHookCallback{fn, arg});
189+
182190
if (promise_hooks_.size() == 1) {
183191
isolate_->SetPromiseHook(EnvPromiseHook);
184192
}
185193
}
186194

195+
bool Environment::RemovePromiseHook(promise_hook_func fn, void* arg) {
196+
auto it = std::find_if(
197+
promise_hooks_.begin(), promise_hooks_.end(),
198+
[&](const PromiseHookCallback& hook) {
199+
return hook.cb_ == fn && hook.arg_ == arg;
200+
});
201+
202+
if (it == promise_hooks_.end()) return false;
203+
204+
promise_hooks_.erase(it);
205+
if (promise_hooks_.empty()) {
206+
isolate_->SetPromiseHook(nullptr);
207+
}
208+
209+
return true;
210+
}
211+
187212
void Environment::EnvPromiseHook(v8::PromiseHookType type,
188213
v8::Local<v8::Promise> promise,
189214
v8::Local<v8::Value> parent) {

src/env.h

+1
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,7 @@ class Environment {
654654
static const int kContextEmbedderDataIndex = NODE_CONTEXT_EMBEDDER_DATA_INDEX;
655655

656656
void AddPromiseHook(promise_hook_func fn, void* arg);
657+
bool RemovePromiseHook(promise_hook_func fn, void* arg);
657658

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

0 commit comments

Comments
 (0)