Skip to content

Commit 437f387

Browse files
addaleaxcodebytere
authored andcommitted
src: reduce scope of code cache mutex
As indicated in the added comment, this can lead to a deadlock otherwise. In the concrete instance in which I encountered this, the relevant nested call is the one to `require('internal/tty')` inside of the `afterInspector()` function for uncaught exception handling. PR-URL: #33980 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: David Carlier <[email protected]> Reviewed-By: Zeyu Yang <[email protected]> Reviewed-By: Joyee Cheung <[email protected]>
1 parent 9199808 commit 437f387

File tree

1 file changed

+12
-4
lines changed

1 file changed

+12
-4
lines changed

src/node_native_module.cc

+12-4
Original file line numberDiff line numberDiff line change
@@ -252,10 +252,13 @@ MaybeLocal<Function> NativeModuleLoader::LookupAndCompile(
252252
Local<Integer> column_offset = Integer::New(isolate, 0);
253253
ScriptOrigin origin(filename, line_offset, column_offset, True(isolate));
254254

255-
Mutex::ScopedLock lock(code_cache_mutex_);
256-
257255
ScriptCompiler::CachedData* cached_data = nullptr;
258256
{
257+
// Note: The lock here should not extend into the
258+
// `CompileFunctionInContext()` call below, because this function may
259+
// recurse if there is a syntax error during bootstrap (because the fatal
260+
// exception handler is invoked, which may load built-in modules).
261+
Mutex::ScopedLock lock(code_cache_mutex_);
259262
auto cache_it = code_cache_.find(id);
260263
if (cache_it != code_cache_.end()) {
261264
// Transfer ownership to ScriptCompiler::Source later.
@@ -302,8 +305,13 @@ MaybeLocal<Function> NativeModuleLoader::LookupAndCompile(
302305
ScriptCompiler::CreateCodeCacheForFunction(fun));
303306
CHECK_NOT_NULL(new_cached_data);
304307

305-
// The old entry should've been erased by now so we can just emplace
306-
code_cache_.emplace(id, std::move(new_cached_data));
308+
{
309+
Mutex::ScopedLock lock(code_cache_mutex_);
310+
// The old entry should've been erased by now so we can just emplace.
311+
// If another thread did the same thing in the meantime, that should not
312+
// be an issue.
313+
code_cache_.emplace(id, std::move(new_cached_data));
314+
}
307315

308316
return scope.Escape(fun);
309317
}

0 commit comments

Comments
 (0)