summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAnna Henningsen <anna@addaleax.net>2019-11-24 00:34:36 +0100
committerAnna Henningsen <anna@addaleax.net>2019-11-29 02:17:12 +0100
commitfad952adbd8a2508d62c6df7ab20376d3898e228 (patch)
treea27475731ef2b778de617609574c1d11acec55fa /src
parentff48009fefcecedfee2c6ff1719e5be3f6969049 (diff)
downloadandroid-node-v8-fad952adbd8a2508d62c6df7ab20376d3898e228.tar.gz
android-node-v8-fad952adbd8a2508d62c6df7ab20376d3898e228.tar.bz2
android-node-v8-fad952adbd8a2508d62c6df7ab20376d3898e228.zip
src: use uv_async_t for WeakRefs
Schedule a task on the main event loop, similar to what the HTML spec recommends for browsers. Alternative to https://github.com/nodejs/node/pull/30198 PR-URL: https://github.com/nodejs/node/pull/30616 Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Diffstat (limited to 'src')
-rw-r--r--src/env-inl.h1
-rw-r--r--src/env.cc31
-rw-r--r--src/env.h4
3 files changed, 30 insertions, 6 deletions
diff --git a/src/env-inl.h b/src/env-inl.h
index 15b5010deb..d34bd03c7c 100644
--- a/src/env-inl.h
+++ b/src/env-inl.h
@@ -1118,6 +1118,7 @@ void Environment::RemoveCleanupHook(void (*fn)(void*), void* arg) {
inline void Environment::RegisterFinalizationGroupForCleanup(
v8::Local<v8::FinalizationGroup> group) {
cleanup_finalization_groups_.emplace_back(isolate(), group);
+ uv_async_send(&cleanup_finalization_groups_async_);
}
size_t CleanupHookCallback::Hash::operator()(
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) {
diff --git a/src/env.h b/src/env.h
index 78724cebc1..c0c8ac0db4 100644
--- a/src/env.h
+++ b/src/env.h
@@ -1128,7 +1128,8 @@ class Environment : public MemoryRetainer {
void RunAtExitCallbacks();
void RegisterFinalizationGroupForCleanup(v8::Local<v8::FinalizationGroup> fg);
- bool RunWeakRefCleanup();
+ void RunWeakRefCleanup();
+ void CleanupFinalizationGroups();
// Strings and private symbols are shared across shared contexts
// The getters simply proxy to the per-isolate primitive.
@@ -1270,6 +1271,7 @@ class Environment : public MemoryRetainer {
uv_idle_t immediate_idle_handle_;
uv_prepare_t idle_prepare_handle_;
uv_check_t idle_check_handle_;
+ uv_async_t cleanup_finalization_groups_async_;
bool profiler_idle_notifier_started_ = false;
AsyncHooks async_hooks_;