Skip to content

Commit e733628

Browse files
committed
fix: improve resource cleanup in N-API environment and runtime
- Added checks to ensure valid arguments in `js_free_napi_env` and `js_free_runtime` functions, enhancing error handling. - Implemented a locker mechanism to prevent unmatched isolate entries during runtime disposal, ensuring proper resource management. - Adjusted the destructor in `Runtime` to handle module deinitialization more gracefully, maintaining consistency in cleanup operations.
1 parent a1f30db commit e733628

File tree

2 files changed

+24
-8
lines changed

2 files changed

+24
-8
lines changed

NativeScript/napi/v8/jsr.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,13 +161,25 @@ napi_status js_create_napi_env(napi_env* env, napi_runtime runtime) {
161161

162162
napi_status js_free_napi_env(napi_env env) {
163163
if (env == nullptr) return napi_invalid_arg;
164+
JSR::env_to_jsr_cache.erase(env);
164165
env->DeleteMe();
165166
return napi_ok;
166167
}
167168

168169
napi_status js_free_runtime(napi_runtime runtime) {
170+
if (runtime == nullptr) return napi_invalid_arg;
169171
JSR* jsr = (JSR*) runtime;
172+
if (jsr == nullptr || jsr->isolate == nullptr) return napi_invalid_arg;
173+
174+
// Ensure there are no outstanding current-thread isolate entries when
175+
// disposing. This protects teardown from accidental unmatched enters.
176+
v8::Locker locker(jsr->isolate);
177+
while (v8::Isolate::GetCurrent() == jsr->isolate) {
178+
jsr->isolate->Exit();
179+
}
180+
170181
jsr->isolate->Dispose();
182+
jsr->isolate = nullptr;
171183
delete jsr;
172184
return napi_ok;
173185
}

NativeScript/runtime/Runtime.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,21 @@ Runtime::Runtime() {
4040
Runtime::~Runtime() {
4141
currentRuntime_ = nullptr;
4242

43-
modules_.DeInit();
44-
4543
if (env_) {
46-
{
47-
NapiScope scope(env_);
48-
49-
napi_close_handle_scope(env_, globalScope_);
50-
js_free_napi_env(env_);
51-
}
44+
{
45+
// Enter isolate/context for deinit work without creating another
46+
// temporary N-API handle scope. We must close the long-lived
47+
// `globalScope_` in LIFO order.
48+
NapiScope scope(env_, false);
49+
50+
modules_.DeInit();
51+
napi_close_handle_scope(env_, globalScope_);
52+
js_free_napi_env(env_);
53+
}
5254

5355
js_free_runtime(runtime_);
56+
} else {
57+
modules_.DeInit();
5458
}
5559

5660
{

0 commit comments

Comments
 (0)