aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/env.cc8
-rw-r--r--src/env.h2
-rw-r--r--test/cctest/test_environment.cc23
3 files changed, 30 insertions, 3 deletions
diff --git a/src/env.cc b/src/env.cc
index da253fac6d..9034c4e069 100644
--- a/src/env.cc
+++ b/src/env.cc
@@ -530,6 +530,8 @@ void Environment::CleanupHandles() {
Isolate::DisallowJavascriptExecutionScope disallow_js(isolate(),
Isolate::DisallowJavascriptExecutionScope::THROW_ON_FAILURE);
+ RunAndClearNativeImmediates(true /* skip SetUnrefImmediate()s */);
+
for (ReqWrapBase* request : req_wrap_queue_)
request->Cancel();
@@ -645,7 +647,7 @@ void Environment::AtExit(void (*cb)(void* arg), void* arg) {
at_exit_functions_.push_front(ExitCallback{cb, arg});
}
-void Environment::RunAndClearNativeImmediates() {
+void Environment::RunAndClearNativeImmediates(bool only_refed) {
TraceEventScope trace_scope(TRACING_CATEGORY_NODE1(environment),
"RunAndClearNativeImmediates", this);
size_t ref_count = 0;
@@ -662,7 +664,9 @@ void Environment::RunAndClearNativeImmediates() {
if (head->is_refed())
ref_count++;
- head->Call(this);
+ if (head->is_refed() || !only_refed)
+ head->Call(this);
+
if (UNLIKELY(try_catch.HasCaught())) {
if (!try_catch.HasTerminated() && can_call_into_js())
errors::TriggerUncaughtException(isolate(), try_catch);
diff --git a/src/env.h b/src/env.h
index 495d92471a..78724cebc1 100644
--- a/src/env.h
+++ b/src/env.h
@@ -1415,7 +1415,7 @@ class Environment : public MemoryRetainer {
std::unique_ptr<NativeImmediateCallback> native_immediate_callbacks_head_;
NativeImmediateCallback* native_immediate_callbacks_tail_ = nullptr;
- void RunAndClearNativeImmediates();
+ void RunAndClearNativeImmediates(bool only_refed = false);
static void CheckImmediate(uv_check_t* handle);
// Use an unordered_set, so that we have efficient insertion and removal.
diff --git a/test/cctest/test_environment.cc b/test/cctest/test_environment.cc
index cc9b8e4531..0db2963acc 100644
--- a/test/cctest/test_environment.cc
+++ b/test/cctest/test_environment.cc
@@ -185,3 +185,26 @@ static void at_exit_js(void* arg) {
assert(obj->IsObject());
called_at_exit_js = true;
}
+
+TEST_F(EnvironmentTest, SetImmediateCleanup) {
+ int called = 0;
+ int called_unref = 0;
+
+ {
+ const v8::HandleScope handle_scope(isolate_);
+ const Argv argv;
+ Env env {handle_scope, argv};
+
+ (*env)->SetImmediate([&](node::Environment* env_arg) {
+ EXPECT_EQ(env_arg, *env);
+ called++;
+ });
+ (*env)->SetUnrefImmediate([&](node::Environment* env_arg) {
+ EXPECT_EQ(env_arg, *env);
+ called_unref++;
+ });
+ }
+
+ EXPECT_EQ(called, 1);
+ EXPECT_EQ(called_unref, 0);
+}