From 7e680807f861ba145dbc20ea3113a291df99cb81 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Tue, 21 Nov 2017 12:38:27 +0100 Subject: [PATCH] src: add optional keep-alive object to SetImmediate Adds the possibility to keep a strong persistent reference to a JS object while a `SetImmediate()` call is in effect. Backport-PR-URL: https://github.com/nodejs/node/pull/18050 PR-URL: https://github.com/nodejs/node/pull/17183 Reviewed-By: James M Snell Reviewed-By: Franziska Hinkelmann Reviewed-By: Anatoli Papirovski --- src/env-inl.h | 11 +++++++++-- src/env.cc | 2 ++ src/env.h | 7 ++++++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/env-inl.h b/src/env-inl.h index b627cc159eafd9..955cf2688f88fa 100644 --- a/src/env-inl.h +++ b/src/env-inl.h @@ -506,8 +506,15 @@ Environment::scheduled_immediate_count() { return scheduled_immediate_count_; } -void Environment::SetImmediate(native_immediate_callback cb, void* data) { - native_immediate_callbacks_.push_back({ cb, data }); +void Environment::SetImmediate(native_immediate_callback cb, + void* data, + v8::Local obj) { + native_immediate_callbacks_.push_back({ + cb, + data, + std::unique_ptr>( + obj.IsEmpty() ? nullptr : new v8::Persistent(isolate_, obj)) + }); if (scheduled_immediate_count_[0] == 0) ActivateImmediateCheck(); scheduled_immediate_count_[0] = scheduled_immediate_count_[0] + 1; diff --git a/src/env.cc b/src/env.cc index 8f8255819b4a28..64fc2dea04e8d1 100644 --- a/src/env.cc +++ b/src/env.cc @@ -276,6 +276,8 @@ void Environment::RunAndClearNativeImmediates() { native_immediate_callbacks_.swap(list); for (const auto& cb : list) { cb.cb_(this, cb.data_); + if (cb.keep_alive_) + cb.keep_alive_->Reset(); } #ifdef DEBUG diff --git a/src/env.h b/src/env.h index 99491c5dbd11eb..9414e357162d93 100644 --- a/src/env.h +++ b/src/env.h @@ -661,7 +661,11 @@ class Environment { bool EmitNapiWarning(); typedef void (*native_immediate_callback)(Environment* env, void* data); - inline void SetImmediate(native_immediate_callback cb, void* data); + // cb will be called as cb(env, data) on the next event loop iteration. + // obj will be kept alive between now and after the callback has run. + inline void SetImmediate(native_immediate_callback cb, + void* data, + v8::Local obj = v8::Local()); // This needs to be available for the JS-land setImmediate(). void ActivateImmediateCheck(); @@ -741,6 +745,7 @@ class Environment { struct NativeImmediateCallback { native_immediate_callback cb_; void* data_; + std::unique_ptr> keep_alive_; }; std::vector native_immediate_callbacks_; void RunAndClearNativeImmediates();