| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1411,9 +1411,19 @@ void Environment::RunAndClearInterrupts() { | |||
| 1411 | 1411 | } | |
| 1412 | 1412 | } | |
| 1413 | 1413 | ||
| 1414 | + bool Environment::HasNativeImmediates() const { | ||
| 1415 | + return native_immediates_.size() > 0 || | ||
| 1416 | + native_immediates_threadsafe_.size() > 0 || | ||
| 1417 | + native_immediates_interrupts_.size() > 0; | ||
| 1418 | + } | ||
| 1419 | + | ||
| 1414 | 1420 | void Environment::RunAndClearNativeImmediates(bool only_refed) { | |
| 1415 | 1421 | TRACE_EVENT0(TRACING_CATEGORY_NODE1(environment), | |
| 1416 | 1422 | "RunAndClearNativeImmediates"); | |
| 1423 | + if (!HasNativeImmediates()) { | ||
| 1424 | + return; | ||
| 1425 | + } | ||
| 1426 | + | ||
| 1417 | 1427 | HandleScope handle_scope(isolate_); | |
| 1418 | 1428 | // In case the Isolate is no longer accessible just use an empty Local. This | |
| 1419 | 1429 | // is not an issue for InternalCallbackScope as this case is already handled | |
@@ -1586,6 +1596,9 @@ void Environment::CheckImmediate(uv_check_t* handle) { | |||
| 1586 | 1596 | Environment* env = Environment::from_immediate_check_handle(handle); | |
| 1587 | 1597 | TRACE_EVENT0(TRACING_CATEGORY_NODE1(environment), "CheckImmediate"); | |
| 1588 | 1598 | ||
| 1599 | + if (env->immediate_info()->count() == 0 && !env->HasNativeImmediates()) | ||
| 1600 | + return; | ||
| 1601 | + | ||
| 1589 | 1602 | HandleScope scope(env->isolate()); | |
| 1590 | 1603 | Context::Scope context_scope(env->context()); | |
| 1591 | 1604 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1037,6 +1037,7 @@ class Environment final : public MemoryRetainer { | |||
| 1037 | 1037 | ||
| 1038 | 1038 | void RunAndClearNativeImmediates(bool only_refed = false); | |
| 1039 | 1039 | void RunAndClearInterrupts(); | |
| 1040 | + bool HasNativeImmediates() const; | ||
| 1040 | 1041 | ||
| 1041 | 1042 | uv_buf_t allocate_managed_buffer(const size_t suggested_size); | |
| 1042 | 1043 | std::unique_ptr<v8::BackingStore> release_managed_buffer(const uv_buf_t& buf); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -401,6 +401,69 @@ TEST_F(EnvironmentTest, SetImmediateCleanup) { | |||
| 401 | 401 | EXPECT_EQ(called_unref, 0); | |
| 402 | 402 | } | |
| 403 | 403 | ||
| 404 | + TEST_F(EnvironmentTest, RunAndClearNativeImmediatesSkipsEmptyScope) { | ||
| 405 | + const v8::HandleScope handle_scope(isolate_); | ||
| 406 | + const Argv argv; | ||
| 407 | + Env env{handle_scope, argv}; | ||
| 408 | + v8::Local<v8::Context> context = env.context(); | ||
| 409 | + | ||
| 410 | + using IntVec = std::vector<int>; | ||
| 411 | + IntVec callback_calls; | ||
| 412 | + v8::Local<v8::Function> must_call = | ||
| 413 | + v8::Function::New( | ||
| 414 | + context, | ||
| 415 | + [](const v8::FunctionCallbackInfo<v8::Value>& info) { | ||
| 416 | + IntVec* callback_calls = | ||
| 417 | + static_cast<IntVec*>(info.Data().As<v8::External>()->Value( | ||
| 418 | + v8::kExternalPointerTypeTagDefault)); | ||
| 419 | + callback_calls->push_back(info[0].As<v8::Int32>()->Value()); | ||
| 420 | + }, | ||
| 421 | + v8::External::New(isolate_, | ||
| 422 | + static_cast<void*>(&callback_calls), | ||
| 423 | + v8::kExternalPointerTypeTagDefault)) | ||
| 424 | + .ToLocalChecked(); | ||
| 425 | + context->Global() | ||
| 426 | + ->Set(context, | ||
| 427 | + v8::String::NewFromUtf8Literal(isolate_, "mustCall"), | ||
| 428 | + must_call) | ||
| 429 | + .Check(); | ||
| 430 | + | ||
| 431 | + v8::Local<v8::Function> eval_in_env = | ||
| 432 | + node::LoadEnvironment(*env, "return eval;") | ||
| 433 | + .ToLocalChecked() | ||
| 434 | + .As<v8::Function>(); | ||
| 435 | + | ||
| 436 | + v8::Local<v8::Value> queue_microtask = v8::String::NewFromUtf8Literal( | ||
| 437 | + isolate_, "Promise.resolve().then(() => mustCall(1));"); | ||
| 438 | + eval_in_env->Call(context, v8::Null(isolate_), 1, &queue_microtask) | ||
| 439 | + .ToLocalChecked(); | ||
| 440 | + EXPECT_TRUE(callback_calls.empty()); | ||
| 441 | + (*env)->RunAndClearNativeImmediates(); | ||
| 442 | + EXPECT_TRUE(callback_calls.empty()); | ||
| 443 | + | ||
| 444 | + context->GetMicrotaskQueue()->PerformCheckpoint(isolate_); | ||
| 445 | + EXPECT_EQ(callback_calls, (IntVec{1})); | ||
| 446 | + callback_calls.clear(); | ||
| 447 | + | ||
| 448 | + queue_microtask = v8::String::NewFromUtf8Literal( | ||
| 449 | + isolate_, "Promise.resolve().then(() => mustCall(2));"); | ||
| 450 | + eval_in_env->Call(context, v8::Null(isolate_), 1, &queue_microtask) | ||
| 451 | + .ToLocalChecked(); | ||
| 452 | + EXPECT_TRUE(callback_calls.empty()); | ||
| 453 | + | ||
| 454 | + bool native_immediate_called = false; | ||
| 455 | + (*env)->SetImmediate( | ||
| 456 | + [&](node::Environment* env_arg) { | ||
| 457 | + EXPECT_EQ(env_arg, *env); | ||
| 458 | + native_immediate_called = true; | ||
| 459 | + }, | ||
| 460 | + node::CallbackFlags::kRefed); | ||
| 461 | + | ||
| 462 | + (*env)->RunAndClearNativeImmediates(); | ||
| 463 | + EXPECT_TRUE(native_immediate_called); | ||
| 464 | + EXPECT_EQ(callback_calls, (IntVec{2})); | ||
| 465 | + } | ||
| 466 | + | ||
| 404 | 467 | static char hello[] = "hello"; | |
| 405 | 468 | ||
| 406 | 469 | TEST_F(EnvironmentTest, BufferWithFreeCallbackIsDetached) { | |
| Back | FazBrowse Home | New Git URL |
0 commit comments