Skip to content

Commit 7d92ac7

Browse files
committed
src: make FreeEnvironment() perform all necessary cleanup
Make the calls `stop_sub_worker_contexts()`, `RunCleanup()` part of the public API for easier embedding. (Note that calling `RunAtExit()` is idempotent because the at-exit callback queue is cleared after each call.) Backport-PR-URL: #35241 PR-URL: #30467 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Gireesh Punathil <[email protected]>
1 parent 1d3638b commit 7d92ac7

File tree

5 files changed

+38
-32
lines changed

5 files changed

+38
-32
lines changed

src/api/environment.cc

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,23 @@ Environment* CreateEnvironment(IsolateData* isolate_data,
342342
}
343343

344344
void FreeEnvironment(Environment* env) {
345-
env->RunCleanup();
345+
{
346+
// TODO(addaleax): This should maybe rather be in a SealHandleScope.
347+
HandleScope handle_scope(env->isolate());
348+
Context::Scope context_scope(env->context());
349+
env->set_stopping(true);
350+
env->stop_sub_worker_contexts();
351+
env->RunCleanup();
352+
RunAtExit(env);
353+
}
354+
355+
// This call needs to be made while the `Environment` is still alive
356+
// because we assume that it is available for async tracking in the
357+
// NodePlatform implementation.
358+
MultiIsolatePlatform* platform = env->isolate_data()->platform();
359+
if (platform != nullptr)
360+
platform->DrainTasks(env->isolate());
361+
346362
delete env;
347363
}
348364

src/node_main_instance.cc

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,8 @@ int NodeMainInstance::Run() {
110110
HandleScope handle_scope(isolate_);
111111

112112
int exit_code = 0;
113-
std::unique_ptr<Environment> env = CreateMainEnvironment(&exit_code);
113+
DeleteFnPtr<Environment, FreeEnvironment> env =
114+
CreateMainEnvironment(&exit_code);
114115

115116
CHECK_NOT_NULL(env);
116117
Context::Scope context_scope(env->context());
@@ -149,10 +150,7 @@ int NodeMainInstance::Run() {
149150
exit_code = EmitExit(env.get());
150151
}
151152

152-
env->set_can_call_into_js(false);
153-
env->stop_sub_worker_contexts();
154153
ResetStdio();
155-
env->RunCleanup();
156154

157155
// TODO(addaleax): Neither NODE_SHARED_MODE nor HAVE_INSPECTOR really
158156
// make sense here.
@@ -167,10 +165,6 @@ int NodeMainInstance::Run() {
167165
}
168166
#endif
169167

170-
RunAtExit(env.get());
171-
172-
per_process::v8_platform.DrainVMTasks(isolate_);
173-
174168
#if defined(LEAK_SANITIZER)
175169
__lsan_do_leak_check();
176170
#endif
@@ -180,8 +174,8 @@ int NodeMainInstance::Run() {
180174

181175
// TODO(joyeecheung): align this with the CreateEnvironment exposed in node.h
182176
// and the environment creation routine in workers somehow.
183-
std::unique_ptr<Environment> NodeMainInstance::CreateMainEnvironment(
184-
int* exit_code) {
177+
DeleteFnPtr<Environment, FreeEnvironment>
178+
NodeMainInstance::CreateMainEnvironment(int* exit_code) {
185179
*exit_code = 0; // Reset the exit code to 0
186180

187181
HandleScope handle_scope(isolate_);
@@ -205,14 +199,14 @@ std::unique_ptr<Environment> NodeMainInstance::CreateMainEnvironment(
205199
CHECK(!context.IsEmpty());
206200
Context::Scope context_scope(context);
207201

208-
std::unique_ptr<Environment> env = std::make_unique<Environment>(
202+
DeleteFnPtr<Environment, FreeEnvironment> env { new Environment(
209203
isolate_data_.get(),
210204
context,
211205
args_,
212206
exec_args_,
213207
static_cast<Environment::Flags>(Environment::kIsMainThread |
214208
Environment::kOwnsProcessState |
215-
Environment::kOwnsInspector));
209+
Environment::kOwnsInspector)) };
216210
env->InitializeLibuv(per_process::v8_is_profiling);
217211
env->InitializeDiagnostics();
218212

src/node_main_instance.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ class NodeMainInstance {
6161

6262
// TODO(joyeecheung): align this with the CreateEnvironment exposed in node.h
6363
// and the environment creation routine in workers somehow.
64-
std::unique_ptr<Environment> CreateMainEnvironment(int* exit_code);
64+
DeleteFnPtr<Environment, FreeEnvironment> CreateMainEnvironment(
65+
int* exit_code);
6566

6667
// If nullptr is returned, the binary is not built with embedded
6768
// snapshot.

src/node_platform.cc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,7 @@ void PerIsolatePlatformData::RunForegroundTask(uv_timer_t* handle) {
402402

403403
void NodePlatform::DrainTasks(Isolate* isolate) {
404404
std::shared_ptr<PerIsolatePlatformData> per_isolate = ForIsolate(isolate);
405+
if (!per_isolate) return;
405406

406407
do {
407408
// Worker tasks aren't associated with an Isolate.
@@ -468,7 +469,9 @@ NodePlatform::ForIsolate(Isolate* isolate) {
468469
}
469470

470471
bool NodePlatform::FlushForegroundTasks(Isolate* isolate) {
471-
return ForIsolate(isolate)->FlushForegroundTasksInternal();
472+
std::shared_ptr<PerIsolatePlatformData> per_isolate = ForIsolate(isolate);
473+
if (!per_isolate) return false;
474+
return per_isolate->FlushForegroundTasksInternal();
472475
}
473476

474477
bool NodePlatform::IdleTasksEnabled(Isolate* isolate) { return false; }

src/node_worker.cc

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -280,26 +280,18 @@ void Worker::Run() {
280280

281281
if (!env_) return;
282282
env_->set_can_call_into_js(false);
283-
Isolate::DisallowJavascriptExecutionScope disallow_js(isolate_,
284-
Isolate::DisallowJavascriptExecutionScope::THROW_ON_FAILURE);
285283

286284
{
287-
Context::Scope context_scope(env_->context());
288-
{
289-
Mutex::ScopedLock lock(mutex_);
290-
stopped_ = true;
291-
this->env_ = nullptr;
292-
}
293-
env_->set_stopping(true);
294-
env_->stop_sub_worker_contexts();
295-
env_->RunCleanup();
296-
RunAtExit(env_.get());
297-
298-
// This call needs to be made while the `Environment` is still alive
299-
// because we assume that it is available for async tracking in the
300-
// NodePlatform implementation.
301-
platform_->DrainTasks(isolate_);
285+
Mutex::ScopedLock lock(mutex_);
286+
stopped_ = true;
287+
this->env_ = nullptr;
302288
}
289+
290+
// TODO(addaleax): Try moving DisallowJavascriptExecutionScope into
291+
// FreeEnvironment().
292+
Isolate::DisallowJavascriptExecutionScope disallow_js(isolate_,
293+
Isolate::DisallowJavascriptExecutionScope::THROW_ON_FAILURE);
294+
env_.reset();
303295
});
304296

305297
if (is_stopped()) return;

0 commit comments

Comments
 (0)