Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fixup! n-api: keep napi_env alive while it has finalizers
  • Loading branch information
addaleax committed Dec 30, 2019
commit ac502fab4fdb165d6d485219e84e18b30fb5e6a8
27 changes: 21 additions & 6 deletions src/js_native_api_v8.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,29 +186,43 @@ inline v8::Local<v8::Value> V8LocalValueFromJsValue(napi_value v) {

// Adapter for napi_finalize callbacks.
class Finalizer {
public:
// Some Finalizers are run during shutdown when the napi_env is destroyed,
// and some need to keep an explicit reference to the napi_env because they
// are run independently.
enum EnvReferenceMode {
kNoEnvReference,
kKeepEnvReference
};

protected:
Finalizer(napi_env env,
napi_finalize finalize_callback,
void* finalize_data,
void* finalize_hint)
void* finalize_hint,
EnvReferenceMode refmode = kNoEnvReference)
: _env(env),
_finalize_callback(finalize_callback),
_finalize_data(finalize_data),
_finalize_hint(finalize_hint) {
_env->Ref();
_finalize_hint(finalize_hint),
_has_env_reference(refmode == kKeepEnvReference) {
if (_has_env_reference)
_env->Ref();
}

~Finalizer() {
_env->Unref();
if (_has_env_reference)
_env->Unref();
}

public:
static Finalizer* New(napi_env env,
napi_finalize finalize_callback = nullptr,
void* finalize_data = nullptr,
void* finalize_hint = nullptr) {
void* finalize_hint = nullptr,
EnvReferenceMode refmode = kNoEnvReference) {
return new Finalizer(
env, finalize_callback, finalize_data, finalize_hint);
env, finalize_callback, finalize_data, finalize_hint, refmode);
}

static void Delete(Finalizer* finalizer) {
Expand All @@ -221,6 +235,7 @@ class Finalizer {
void* _finalize_data;
void* _finalize_hint;
bool _finalize_ran = false;
bool _has_env_reference = false;
};

class TryCatch : public v8::TryCatch {
Expand Down
3 changes: 2 additions & 1 deletion src/node_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -732,7 +732,8 @@ napi_status napi_create_external_buffer(napi_env env,

// The finalizer object will delete itself after invoking the callback.
v8impl::Finalizer* finalizer = v8impl::Finalizer::New(
env, finalize_cb, nullptr, finalize_hint);
env, finalize_cb, nullptr, finalize_hint,
v8impl::Finalizer::kKeepEnvReference);

auto maybe = node::Buffer::New(isolate,
static_cast<char*>(data),
Expand Down