Skip to content

Commit 0dd67d9

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 0eed22d commit 0dd67d9

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
@@ -260,10 +260,13 @@ MaybeLocal<Function> NativeModuleLoader::LookupAndCompile(
260260
Local<Integer> column_offset = Integer::New(isolate, 0);
261261
ScriptOrigin origin(filename, line_offset, column_offset, True(isolate));
262262

263-
Mutex::ScopedLock lock(code_cache_mutex_);
264-
265263
ScriptCompiler::CachedData* cached_data = nullptr;
266264
{
265+
// Note: The lock here should not extend into the
266+
// `CompileFunctionInContext()` call below, because this function may
267+
// recurse if there is a syntax error during bootstrap (because the fatal
268+
// exception handler is invoked, which may load built-in modules).
269+
Mutex::ScopedLock lock(code_cache_mutex_);
267270
auto cache_it = code_cache_.find(id);
268271
if (cache_it != code_cache_.end()) {
269272
// Transfer ownership to ScriptCompiler::Source later.
@@ -310,8 +313,13 @@ MaybeLocal<Function> NativeModuleLoader::LookupAndCompile(
310313
ScriptCompiler::CreateCodeCacheForFunction(fun));
311314
CHECK_NOT_NULL(new_cached_data);
312315

313-
// The old entry should've been erased by now so we can just emplace
314-
code_cache_.emplace(id, std::move(new_cached_data));
316+
{
317+
Mutex::ScopedLock lock(code_cache_mutex_);
318+
// The old entry should've been erased by now so we can just emplace.
319+
// If another thread did the same thing in the meantime, that should not
320+
// be an issue.
321+
code_cache_.emplace(id, std::move(new_cached_data));
322+
}
315323

316324
return scope.Escape(fun);
317325
}

0 commit comments

Comments
 (0)