diff options
Diffstat (limited to 'src/env.cc')
-rw-r--r-- | src/env.cc | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/src/env.cc b/src/env.cc index 7f7c51c13c..dc99e4bd53 100644 --- a/src/env.cc +++ b/src/env.cc @@ -459,8 +459,17 @@ void Environment::InitializeLibuv(bool start_profiler_idle_notifier) { // will be recorded with state=IDLE. uv_prepare_init(event_loop(), &idle_prepare_handle_); uv_check_init(event_loop(), &idle_check_handle_); + uv_async_init( + event_loop(), + &cleanup_finalization_groups_async_, + [](uv_async_t* async) { + Environment* env = ContainerOf( + &Environment::cleanup_finalization_groups_async_, async); + env->CleanupFinalizationGroups(); + }); uv_unref(reinterpret_cast<uv_handle_t*>(&idle_prepare_handle_)); uv_unref(reinterpret_cast<uv_handle_t*>(&idle_check_handle_)); + uv_unref(reinterpret_cast<uv_handle_t*>(&cleanup_finalization_groups_async_)); thread_stopper()->Install( this, static_cast<void*>(this), [](uv_async_t* handle) { @@ -523,6 +532,10 @@ void Environment::RegisterHandleCleanups() { reinterpret_cast<uv_handle_t*>(&idle_check_handle_), close_and_finish, nullptr); + RegisterHandleCleanup( + reinterpret_cast<uv_handle_t*>(&cleanup_finalization_groups_async_), + close_and_finish, + nullptr); } void Environment::CleanupHandles() { @@ -1046,19 +1059,27 @@ char* Environment::Reallocate(char* data, size_t old_size, size_t size) { return new_data; } -bool Environment::RunWeakRefCleanup() { +void Environment::RunWeakRefCleanup() { isolate()->ClearKeptObjects(); +} - while (!cleanup_finalization_groups_.empty()) { +void Environment::CleanupFinalizationGroups() { + HandleScope handle_scope(isolate()); + Context::Scope context_scope(context()); + TryCatchScope try_catch(this); + + while (!cleanup_finalization_groups_.empty() && can_call_into_js()) { Local<FinalizationGroup> fg = cleanup_finalization_groups_.front().Get(isolate()); cleanup_finalization_groups_.pop_front(); if (!FinalizationGroup::Cleanup(fg).FromMaybe(false)) { - return false; + if (try_catch.HasCaught() && !try_catch.HasTerminated()) + errors::TriggerUncaughtException(isolate(), try_catch); + // Re-schedule the execution of the remainder of the queue. + uv_async_send(&cleanup_finalization_groups_async_); + return; } } - - return true; } void AsyncRequest::Install(Environment* env, void* data, uv_async_cb target) { |