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/env-inl.h | |
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/env-inl.h')
-rw-r--r-- | src/env-inl.h | 67 |
1 files changed, 50 insertions, 17 deletions
diff --git a/src/env-inl.h b/src/env-inl.h index f970e414f12..3d1aca994ff 100644 --- a/src/env-inl.h +++ b/src/env-inl.h @@ -753,33 +753,66 @@ inline void IsolateData::set_options( options_ = std::move(options); } -void Environment::CreateImmediate(native_immediate_callback cb, - void* data, - v8::Local<v8::Object> obj, +template <typename Fn> +void Environment::CreateImmediate(Fn&& cb, + v8::Local<v8::Object> keep_alive, bool ref) { - native_immediate_callbacks_.push_back({ - cb, - data, - v8::Global<v8::Object>(isolate_, obj), - ref - }); + auto callback = std::make_unique<NativeImmediateCallbackImpl<Fn>>( + std::move(cb), + v8::Global<v8::Object>(isolate(), keep_alive), + ref); + NativeImmediateCallback* prev_tail = native_immediate_callbacks_tail_; + + native_immediate_callbacks_tail_ = callback.get(); + if (prev_tail != nullptr) + prev_tail->set_next(std::move(callback)); + else + native_immediate_callbacks_head_ = std::move(callback); + immediate_info()->count_inc(1); } -void Environment::SetImmediate(native_immediate_callback cb, - void* data, - v8::Local<v8::Object> obj) { - CreateImmediate(cb, data, obj, true); +template <typename Fn> +void Environment::SetImmediate(Fn&& cb, v8::Local<v8::Object> keep_alive) { + CreateImmediate(std::move(cb), keep_alive, true); if (immediate_info()->ref_count() == 0) ToggleImmediateRef(true); immediate_info()->ref_count_inc(1); } -void Environment::SetUnrefImmediate(native_immediate_callback cb, - void* data, - v8::Local<v8::Object> obj) { - CreateImmediate(cb, data, obj, false); +template <typename Fn> +void Environment::SetUnrefImmediate(Fn&& cb, v8::Local<v8::Object> keep_alive) { + CreateImmediate(std::move(cb), keep_alive, false); +} + +Environment::NativeImmediateCallback::NativeImmediateCallback(bool refed) + : refed_(refed) {} + +bool Environment::NativeImmediateCallback::is_refed() const { + return refed_; +} + +std::unique_ptr<Environment::NativeImmediateCallback> +Environment::NativeImmediateCallback::get_next() { + return std::move(next_); +} + +void Environment::NativeImmediateCallback::set_next( + std::unique_ptr<NativeImmediateCallback> next) { + next_ = std::move(next); +} + +template <typename Fn> +Environment::NativeImmediateCallbackImpl<Fn>::NativeImmediateCallbackImpl( + Fn&& callback, v8::Global<v8::Object>&& keep_alive, bool refed) + : NativeImmediateCallback(refed), + callback_(std::move(callback)), + keep_alive_(std::move(keep_alive)) {} + +template <typename Fn> +void Environment::NativeImmediateCallbackImpl<Fn>::Call(Environment* env) { + callback_(env); } inline bool Environment::can_call_into_js() const { |