Skip to content

Commit df3d763

Browse files
committed
src: use correct microtask queue for checkpoints
I missed in c6c8337 that we should not just use that queue for enqueuing microtasks, but also for running them. Refs: nodejs#36482 PR-URL: nodejs#36581 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Gus Caplan <me@gus.host>
1 parent 0e077a5 commit df3d763

File tree

3 files changed

+34
-17
lines changed

3 files changed

+34
-17
lines changed

src/api/callback.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ using v8::HandleScope;
1212
using v8::Isolate;
1313
using v8::Local;
1414
using v8::MaybeLocal;
15-
using v8::MicrotasksScope;
1615
using v8::Object;
1716
using v8::String;
1817
using v8::Value;
@@ -115,7 +114,7 @@ void InternalCallbackScope::Close() {
115114
auto weakref_cleanup = OnScopeLeave([&]() { env_->RunWeakRefCleanup(); });
116115

117116
if (!tick_info->has_tick_scheduled()) {
118-
MicrotasksScope::PerformCheckpoint(env_->isolate());
117+
env_->context()->GetMicrotaskQueue()->PerformCheckpoint(env_->isolate());
119118

120119
perform_stopping_check();
121120
}

src/node_task_queue.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ using v8::kPromiseRejectAfterResolved;
2020
using v8::kPromiseRejectWithNoHandler;
2121
using v8::kPromiseResolveAfterResolved;
2222
using v8::Local;
23-
using v8::MicrotasksScope;
2423
using v8::Number;
2524
using v8::Object;
2625
using v8::Promise;
@@ -100,7 +99,8 @@ static void EnqueueMicrotask(const FunctionCallbackInfo<Value>& args) {
10099
}
101100

102101
static void RunMicrotasks(const FunctionCallbackInfo<Value>& args) {
103-
MicrotasksScope::PerformCheckpoint(args.GetIsolate());
102+
Environment* env = Environment::GetCurrent(args);
103+
env->context()->GetMicrotaskQueue()->PerformCheckpoint(env->isolate());
104104
}
105105

106106
static void SetTickCallback(const FunctionCallbackInfo<Value>& args) {

test/cctest/test_environment.cc

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -660,13 +660,14 @@ TEST_F(EnvironmentTest, NestedMicrotaskQueue) {
660660
node::InitializeContext(context);
661661
v8::Context::Scope context_scope(context);
662662

663-
int callback_calls = 0;
663+
using IntVec = std::vector<int>;
664+
IntVec callback_calls;
664665
v8::Local<v8::Function> must_call = v8::Function::New(
665666
context,
666667
[](const v8::FunctionCallbackInfo<v8::Value>& info) {
667-
int* callback_calls =
668-
static_cast<int*>(info.Data().As<v8::External>()->Value());
669-
*callback_calls |= info[0].As<v8::Int32>()->Value();
668+
IntVec* callback_calls = static_cast<IntVec*>(
669+
info.Data().As<v8::External>()->Value());
670+
callback_calls->push_back(info[0].As<v8::Int32>()->Value());
670671
},
671672
v8::External::New(isolate_, static_cast<void*>(&callback_calls)))
672673
.ToLocalChecked();
@@ -683,23 +684,40 @@ TEST_F(EnvironmentTest, NestedMicrotaskQueue) {
683684
isolate_data, context, {}, {});
684685
CHECK_NE(nullptr, env);
685686

686-
node::LoadEnvironment(
687+
v8::Local<v8::Function> eval_in_env = node::LoadEnvironment(
687688
env,
688-
"Promise.resolve().then(() => mustCall(1 << 0));\n"
689+
"mustCall(1);\n"
690+
"Promise.resolve().then(() => mustCall(2));\n"
689691
"require('vm').runInNewContext("
690-
" 'Promise.resolve().then(() => mustCall(1 << 1))',"
692+
" 'Promise.resolve().then(() => mustCall(3))',"
691693
" { mustCall },"
692694
" { microtaskMode: 'afterEvaluate' }"
693-
");"
695+
");\n"
694696
"require('vm').runInNewContext("
695-
" 'Promise.resolve().then(() => mustCall(1 << 2))',"
697+
" 'Promise.resolve().then(() => mustCall(4))',"
696698
" { mustCall }"
697-
");").ToLocalChecked();
698-
EXPECT_EQ(callback_calls, 1 << 1);
699+
");\n"
700+
"setTimeout(() => {"
701+
" Promise.resolve().then(() => mustCall(5));"
702+
"}, 10);\n"
703+
"mustCall(6);\n"
704+
"return eval;\n").ToLocalChecked().As<v8::Function>();
705+
EXPECT_EQ(callback_calls, (IntVec { 1, 3, 6, 2, 4 }));
706+
v8::Local<v8::Value> queue_microtask_code = v8::String::NewFromUtf8Literal(
707+
isolate_, "queueMicrotask(() => mustCall(7));");
708+
eval_in_env->Call(context,
709+
v8::Null(isolate_),
710+
1,
711+
&queue_microtask_code).ToLocalChecked();
712+
EXPECT_EQ(callback_calls, (IntVec { 1, 3, 6, 2, 4 }));
699713
isolate_->PerformMicrotaskCheckpoint();
700-
EXPECT_EQ(callback_calls, 1 << 1);
714+
EXPECT_EQ(callback_calls, (IntVec { 1, 3, 6, 2, 4 }));
701715
queue->PerformCheckpoint(isolate_);
702-
EXPECT_EQ(callback_calls, (1 << 0) | (1 << 1) | (1 << 2));
716+
EXPECT_EQ(callback_calls, (IntVec { 1, 3, 6, 2, 4, 7 }));
717+
718+
int exit_code = SpinEventLoop(env).FromJust();
719+
EXPECT_EQ(exit_code, 0);
720+
EXPECT_EQ(callback_calls, (IntVec { 1, 3, 6, 2, 4, 7, 5 }));
703721

704722
node::FreeEnvironment(env);
705723
node::FreeIsolateData(isolate_data);

0 commit comments

Comments
 (0)