Skip to content

Commit 286bffc

Browse files
codebytereaduh95
authored andcommitted
src: track handle cleanup per thread, not per IsolateData
The FreeEnvironment() fix for sibling Environments keeps the depth of nested Environment::CleanupHandles() calls on the IsolateData, so that InternalCallbackScope can re-allow JavaScript for sibling Environments while one of them is being freed. Environments that each have their own IsolateData on the same isolate and loop never see that counter and still fail with "illegal access". Environments that share a loop share a thread, so keep the depth in a thread_local instead. Refs: #65977 Signed-off-by: Shelley Vohr <shelley.vohr@gmail.com> PR-URL: #66239 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Chengzhong Wu <legendecas@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>
1 parent f63ddfa commit 286bffc

4 files changed

Lines changed: 10 additions & 9 deletions

File tree

‎src/api/callback.cc‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,7 @@ InternalCallbackScope::InternalCallbackScope(
9696
}
9797

9898
Isolate* isolate = env->isolate();
99-
// See IsolateData::handle_cleanup_depth.
100-
if (env->isolate_data()->handle_cleanup_depth > 0) allow_js_.emplace(isolate);
99+
if (handle_cleanup_depth > 0) allow_js_.emplace(isolate);
101100

102101
HandleScope handle_scope(isolate);
103102
Local<Context> current_context = isolate->GetCurrentContext();

‎src/env.cc‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1452,6 +1452,8 @@ void Environment::ClosePerEnvHandles() {
14521452
close_and_finish(reinterpret_cast<uv_handle_t*>(&task_queues_async_));
14531453
}
14541454

1455+
thread_local int handle_cleanup_depth = 0;
1456+
14551457
void Environment::CleanupHandles() {
14561458
{
14571459
Mutex::ScopedLock lock(native_immediates_threadsafe_mutex_);
@@ -1469,8 +1471,8 @@ void Environment::CleanupHandles() {
14691471
for (HandleWrap* handle : handle_wrap_queue_)
14701472
handle->Close();
14711473

1472-
isolate_data()->handle_cleanup_depth++;
1473-
auto done = OnScopeLeave([&]() { isolate_data()->handle_cleanup_depth--; });
1474+
handle_cleanup_depth++;
1475+
auto done = OnScopeLeave([]() { handle_cleanup_depth--; });
14741476
while (handle_cleanup_waiting_ != 0 ||
14751477
request_waiting_ != 0 ||
14761478
!handle_wrap_queue_.IsEmpty()) {

‎src/env.h‎

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -182,11 +182,6 @@ class NODE_EXTERN_PRIVATE IsolateData : public MemoryRetainer {
182182
inline worker::Worker* worker_context() const;
183183
inline void set_worker_context(worker::Worker* context);
184184

185-
// Non-zero while an Environment on this isolate is closing its handles with
186-
// JS disallowed isolate-wide; InternalCallbackScope re-allows it for the
187-
// other Environments whose callbacks run in those loop turns.
188-
int handle_cleanup_depth = 0;
189-
190185
#define VP(PropertyName, StringValue) V(v8::Private, PropertyName)
191186
#define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName)
192187
#define VS(PropertyName, StringValue) V(v8::String, PropertyName)

‎src/node_internals.h‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,11 @@ class InternalCallbackScope {
283283
std::optional<v8::Isolate::AllowJavascriptExecutionScope> allow_js_;
284284
};
285285

286+
// Non-zero while an Environment on this thread is closing its handles with JS
287+
// disallowed isolate-wide; InternalCallbackScope re-allows it for the other
288+
// Environments whose callbacks run in those loop turns.
289+
extern thread_local int handle_cleanup_depth;
290+
286291
class DebugSealHandleScope {
287292
public:
288293
explicit inline DebugSealHandleScope(v8::Isolate* isolate = nullptr)

0 commit comments

Comments
 (0)