| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 24f7335 commit 50b7f84
5 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1123,6 +1123,7 @@ void Environment::RemoveCleanupHook(void (*fn)(void*), void* arg) { | |||
| 1123 | 1123 | inline void Environment::RegisterFinalizationGroupForCleanup( | |
| 1124 | 1124 | v8::Local<v8::FinalizationGroup> group) { | |
| 1125 | 1125 | cleanup_finalization_groups_.emplace_back(isolate(), group); | |
| 1126 | + uv_async_send(&cleanup_finalization_groups_async_); | ||
| 1126 | 1127 | } | |
| 1127 | 1128 | ||
| 1128 | 1129 | size_t CleanupHookCallback::Hash::operator()( | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -457,8 +457,17 @@ void Environment::InitializeLibuv(bool start_profiler_idle_notifier) { | |||
| 457 | 457 | // will be recorded with state=IDLE. | |
| 458 | 458 | uv_prepare_init(event_loop(), &idle_prepare_handle_); | |
| 459 | 459 | uv_check_init(event_loop(), &idle_check_handle_); | |
| 460 | + uv_async_init( | ||
| 461 | + event_loop(), | ||
| 462 | + &cleanup_finalization_groups_async_, | ||
| 463 | + [](uv_async_t* async) { | ||
| 464 | + Environment* env = ContainerOf( | ||
| 465 | + &Environment::cleanup_finalization_groups_async_, async); | ||
| 466 | + env->CleanupFinalizationGroups(); | ||
| 467 | + }); | ||
| 460 | 468 | uv_unref(reinterpret_cast<uv_handle_t*>(&idle_prepare_handle_)); | |
| 461 | 469 | uv_unref(reinterpret_cast<uv_handle_t*>(&idle_check_handle_)); | |
| 470 | + uv_unref(reinterpret_cast<uv_handle_t*>(&cleanup_finalization_groups_async_)); | ||
| 462 | 471 | ||
| 463 | 472 | thread_stopper()->Install( | |
| 464 | 473 | this, static_cast<void*>(this), [](uv_async_t* handle) { | |
@@ -521,6 +530,10 @@ void Environment::RegisterHandleCleanups() { | |||
| 521 | 530 | reinterpret_cast<uv_handle_t*>(&idle_check_handle_), | |
| 522 | 531 | close_and_finish, | |
| 523 | 532 | nullptr); | |
| 533 | + RegisterHandleCleanup( | ||
| 534 | + reinterpret_cast<uv_handle_t*>(&cleanup_finalization_groups_async_), | ||
| 535 | + close_and_finish, | ||
| 536 | + nullptr); | ||
| 524 | 537 | } | |
| 525 | 538 | ||
| 526 | 539 | void Environment::CleanupHandles() { | |
@@ -1052,19 +1065,27 @@ void Environment::AddArrayBufferAllocatorToKeepAliveUntilIsolateDispose( | |||
| 1052 | 1065 | keep_alive_allocators_->insert(allocator); | |
| 1053 | 1066 | } | |
| 1054 | 1067 | ||
| 1055 | - bool Environment::RunWeakRefCleanup() { | ||
| 1068 | + void Environment::RunWeakRefCleanup() { | ||
| 1056 | 1069 | isolate()->ClearKeptObjects(); | |
| 1070 | + } | ||
| 1057 | 1071 | ||
| 1058 | - while (!cleanup_finalization_groups_.empty()) { | ||
| 1072 | + void Environment::CleanupFinalizationGroups() { | ||
| 1073 | + HandleScope handle_scope(isolate()); | ||
| 1074 | + Context::Scope context_scope(context()); | ||
| 1075 | + TryCatchScope try_catch(this); | ||
| 1076 | + | ||
| 1077 | + while (!cleanup_finalization_groups_.empty() && can_call_into_js()) { | ||
| 1059 | 1078 | Local<FinalizationGroup> fg = | |
| 1060 | 1079 | cleanup_finalization_groups_.front().Get(isolate()); | |
| 1061 | 1080 | cleanup_finalization_groups_.pop_front(); | |
| 1062 | 1081 | if (!FinalizationGroup::Cleanup(fg).FromMaybe(false)) { | |
| 1063 | - return false; | ||
| 1082 | + if (try_catch.HasCaught() && !try_catch.HasTerminated()) | ||
| 1083 | + errors::TriggerUncaughtException(isolate(), try_catch); | ||
| 1084 | + // Re-schedule the execution of the remainder of the queue. | ||
| 1085 | + uv_async_send(&cleanup_finalization_groups_async_); | ||
| 1086 | + return; | ||
| 1064 | 1087 | } | |
| 1065 | 1088 | } | |
| 1066 | - | ||
| 1067 | - return true; | ||
| 1068 | 1089 | } | |
| 1069 | 1090 | ||
| 1070 | 1091 | void AsyncRequest::Install(Environment* env, void* data, uv_async_cb target) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1130,7 +1130,8 @@ class Environment : public MemoryRetainer { | |||
| 1130 | 1130 | void RunAtExitCallbacks(); | |
| 1131 | 1131 | ||
| 1132 | 1132 | void RegisterFinalizationGroupForCleanup(v8::Local<v8::FinalizationGroup> fg); | |
| 1133 | - bool RunWeakRefCleanup(); | ||
| 1133 | + void RunWeakRefCleanup(); | ||
| 1134 | + void CleanupFinalizationGroups(); | ||
| 1134 | 1135 | ||
| 1135 | 1136 | // Strings and private symbols are shared across shared contexts | |
| 1136 | 1137 | // The getters simply proxy to the per-isolate primitive. | |
@@ -1276,6 +1277,7 @@ class Environment : public MemoryRetainer { | |||
| 1276 | 1277 | uv_idle_t immediate_idle_handle_; | |
| 1277 | 1278 | uv_prepare_t idle_prepare_handle_; | |
| 1278 | 1279 | uv_check_t idle_check_handle_; | |
| 1280 | + uv_async_t cleanup_finalization_groups_async_; | ||
| 1279 | 1281 | bool profiler_idle_notifier_started_ = false; | |
| 1280 | 1282 | ||
| 1281 | 1283 | AsyncHooks async_hooks_; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -18,6 +18,10 @@ setTimeout(() => { | |||
| 18 | 18 | name: 'Error', | |
| 19 | 19 | message: 'test', | |
| 20 | 20 | }); | |
| 21 | + | ||
| 22 | + // Give the callbacks scheduled by global.gc() time to run, as the underlying | ||
| 23 | + // uv_async_t is unref’ed. | ||
| 24 | + setTimeout(() => {}, 200); | ||
| 21 | 25 | }, 200); | |
| 22 | 26 | ||
| 23 | 27 | process.on('uncaughtException', common.mustCall()); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,25 @@ | |||
| 1 | + // Flags: --harmony-weak-refs | ||
| 2 | + 'use strict'; | ||
| 3 | + require('../common'); | ||
| 4 | + const assert = require('assert'); | ||
| 5 | + | ||
| 6 | + // Test that finalization callbacks do not crash when caused through a regular | ||
| 7 | + // GC (not global.gc()). | ||
| 8 | + | ||
| 9 | + const start = Date.now(); | ||
| 10 | + const g = new globalThis.FinalizationGroup(() => { | ||
| 11 | + const diff = Date.now() - start; | ||
| 12 | + assert(diff < 10000, `${diff} >= 10000`); | ||
| 13 | + }); | ||
| 14 | + g.register({}, 42); | ||
| 15 | + | ||
| 16 | + setImmediate(() => { | ||
| 17 | + const arr = []; | ||
| 18 | + // Build up enough memory usage to hopefully trigger a platform task but not | ||
| 19 | + // enough to trigger GC as an interrupt. | ||
| 20 | + while (arr.length < 1000000) arr.push([]); | ||
| 21 | + | ||
| 22 | + setTimeout(() => { | ||
| 23 | + g; // Keep reference alive. | ||
| 24 | + }, 200000).unref(); | ||
| 25 | + }); | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments