Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions v8/src/edge_v8_platform.cc
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,20 @@ void EdgeV8Platform::ClearForegroundTaskTarget(v8::Isolate* isolate, napi_env en
state->runner->ClearTarget(env);
}

void EdgeV8Platform::PumpPendingForegroundTasks(v8::Isolate* isolate) {
if (fallback_ == nullptr || isolate == nullptr) return;
// ForegroundTaskRunner::PostTaskCommon forwards to the guest's bound
// enqueue callback when one is set, but falls back to fallback_'s own
// GetForegroundTaskRunner() when no guest target is bound (e.g. the guest
// drives everything through unofficial_napi_process_microtasks and never
// calls BindForegroundTaskTarget). Nothing else pumps that fallback
// runner's queue, so tasks routed there -- including V8-internal work like
// Heap::PostFinalizationRegistryCleanupTaskIfNeeded's cleanup task -- would
// otherwise be posted and never run. Drain it explicitly.
while (v8::platform::PumpMessageLoop(fallback_.get(), isolate)) {
}
}

int EdgeV8Platform::NumberOfWorkerThreads() {
return fallback_ != nullptr ? fallback_->NumberOfWorkerThreads() : 0;
}
Expand Down
1 change: 1 addition & 0 deletions v8/src/edge_v8_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class EdgeV8Platform final : public v8::Platform {
void ClearForegroundTaskTarget(v8::Isolate* isolate, napi_env env);
void AddPendingForegroundTask(const std::shared_ptr<IsolateState>& state);
void CompletePendingForegroundTask(const std::shared_ptr<IsolateState>& state);
void PumpPendingForegroundTasks(v8::Isolate* isolate);

int NumberOfWorkerThreads() override;
std::shared_ptr<v8::TaskRunner> GetForegroundTaskRunner(
Expand Down
28 changes: 28 additions & 0 deletions v8/src/unofficial_napi.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2142,6 +2142,32 @@ napi_status NAPI_CDECL unofficial_napi_set_prepare_stack_trace_callback(
return napi_ok;
}

// V8 posts some of its own deferred foreground work (most notably
// Heap::PostFinalizationRegistryCleanupTaskIfNeeded's cleanup task, run after
// GC finds a JSFinalizationRegistry with dead targets) via
// v8::TaskRunner::PostNonNestableTask on the runner EdgeV8Platform hands back
// for the isolate. That runner forwards to the guest's own enqueue callback
// when one is bound (see EdgeV8Platform::BindForegroundTaskTarget), but the
// guest is not required to bind one -- it may drive everything through
// unofficial_napi_process_microtasks instead. Tasks posted with no guest
// target bound fall back to the stock default-platform runner, and nothing
// else ever pumps that runner's queue, so without this they are posted and
// then never run: V8 correctly collects the dead targets, but their
// FinalizationRegistry callbacks never fire. Pump it here, at the same point
// microtasks are already checkpointed, so this deferred work always gets a
// chance to run regardless of whether the guest wired up its own hook.
void PumpPlatformForegroundTasks(napi_env env) {
if (env == nullptr || env->isolate == nullptr) return;
EdgeV8Platform* platform = nullptr;
{
std::lock_guard<std::mutex> lock(g_runtime_mu);
platform = g_runtime.platform.get();
}
if (platform != nullptr) {
platform->PumpPendingForegroundTasks(env->isolate);
}
}

void DrainMicrotasksForEnv(napi_env env) {
if (env == nullptr || env->isolate == nullptr) return;
env->DrainFinalizerQueue();
Expand All @@ -2151,11 +2177,13 @@ void DrainMicrotasksForEnv(napi_env env) {
if (queue != nullptr) {
queue->PerformCheckpoint(env->isolate);
env->DrainFinalizerQueue();
PumpPlatformForegroundTasks(env);
return;
}
}
env->isolate->PerformMicrotaskCheckpoint();
env->DrainFinalizerQueue();
PumpPlatformForegroundTasks(env);
}

napi_status NAPI_CDECL unofficial_napi_request_gc_for_testing(napi_env env) {
Expand Down
Loading