diff options
author | Anna Henningsen <anna@addaleax.net> | 2019-07-15 23:17:45 +0300 |
---|---|---|
committer | Anna Henningsen <anna@addaleax.net> | 2019-08-01 01:51:43 +0300 |
commit | 5207dec0175de92116262e8382d6ac57def3a203 (patch) | |
tree | e90e855f7a8a228e00fe0d49fb311b319de74c3d /src/node_api.cc | |
parent | 61f3a5c60ad78506e9e0caae061a04ccab878ca1 (diff) |
src: allow generic C++ callables in SetImmediate()
Modify the native `SetImmediate()` functions to take generic C++
callables as arguments. This makes passing arguments to the callback
easier, and in particular, it allows passing `std::unique_ptr`s
directly, which in turn makes sure that the data they point to is
deleted if the `Environment` is torn down before the callback can run.
PR-URL: https://github.com/nodejs/node/pull/28704
Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'src/node_api.cc')
-rw-r--r-- | src/node_api.cc | 42 |
1 files changed, 24 insertions, 18 deletions
diff --git a/src/node_api.cc b/src/node_api.cc index 49472930634..95664e9c7ac 100644 --- a/src/node_api.cc +++ b/src/node_api.cc @@ -36,27 +36,33 @@ class BufferFinalizer : private Finalizer { public: // node::Buffer::FreeCallback static void FinalizeBufferCallback(char* data, void* hint) { - BufferFinalizer* finalizer = static_cast<BufferFinalizer*>(hint); + std::unique_ptr<BufferFinalizer, Deleter> finalizer{ + static_cast<BufferFinalizer*>(hint)}; finalizer->_finalize_data = data; - static_cast<node_napi_env>(finalizer->_env)->node_env() - ->SetImmediate([](node::Environment* env, void* hint) { - BufferFinalizer* finalizer = static_cast<BufferFinalizer*>(hint); - - if (finalizer->_finalize_callback != nullptr) { - v8::HandleScope handle_scope(finalizer->_env->isolate); - v8::Context::Scope context_scope(finalizer->_env->context()); - - finalizer->_env->CallIntoModuleThrow([&](napi_env env) { - finalizer->_finalize_callback( - env, - finalizer->_finalize_data, - finalizer->_finalize_hint); - }); - } - Delete(finalizer); - }, hint); + node::Environment* node_env = + static_cast<node_napi_env>(finalizer->_env)->node_env(); + node_env->SetImmediate( + [finalizer = std::move(finalizer)](node::Environment* env) { + if (finalizer->_finalize_callback == nullptr) return; + + v8::HandleScope handle_scope(finalizer->_env->isolate); + v8::Context::Scope context_scope(finalizer->_env->context()); + + finalizer->_env->CallIntoModuleThrow([&](napi_env env) { + finalizer->_finalize_callback( + env, + finalizer->_finalize_data, + finalizer->_finalize_hint); + }); + }); } + + struct Deleter { + void operator()(BufferFinalizer* finalizer) { + Finalizer::Delete(finalizer); + } + }; }; static inline napi_env NewEnv(v8::Local<v8::Context> context) { |