Skip to content

Commit

Permalink
src: add optional keep-alive object to SetImmediate
Browse files Browse the repository at this point in the history
Adds the possibility to keep a strong persistent reference to
a JS object while a `SetImmediate()` call is in effect.

Backport-PR-URL: nodejs#18050
PR-URL: nodejs#17183
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
  • Loading branch information
addaleax authored and kjin committed Apr 30, 2018
1 parent 14d0bab commit 584379f
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 3 deletions.
11 changes: 9 additions & 2 deletions src/env-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -541,8 +541,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<v8::Object> obj) {
native_immediate_callbacks_.push_back({
cb,
data,
std::unique_ptr<v8::Persistent<v8::Object>>(
obj.IsEmpty() ? nullptr : new v8::Persistent<v8::Object>(isolate_, obj))
});
if (scheduled_immediate_count_[0] == 0)
ActivateImmediateCheck();
scheduled_immediate_count_[0] = scheduled_immediate_count_[0] + 1;
Expand Down
2 changes: 2 additions & 0 deletions src/env.cc
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,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
Expand Down
7 changes: 6 additions & 1 deletion src/env.h
Original file line number Diff line number Diff line change
Expand Up @@ -686,7 +686,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<v8::Object> obj = v8::Local<v8::Object>());
// This needs to be available for the JS-land setImmediate().
void ActivateImmediateCheck();

Expand Down Expand Up @@ -754,6 +758,7 @@ class Environment {
struct NativeImmediateCallback {
native_immediate_callback cb_;
void* data_;
std::unique_ptr<v8::Persistent<v8::Object>> keep_alive_;
};
std::vector<NativeImmediateCallback> native_immediate_callbacks_;
void RunAndClearNativeImmediates();
Expand Down

0 comments on commit 584379f

Please sign in to comment.