Skip to content

Commit d8f8723

Browse files
addaleaxdanbev
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 8ada275 commit d8f8723

File tree

1 file changed

+12
-4
lines changed

1 file changed

+12
-4
lines changed

src/node_native_module.cc

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -263,10 +263,13 @@ MaybeLocal<Function> NativeModuleLoader::LookupAndCompile(
263263
Local<Integer> column_offset = Integer::New(isolate, 0);
264264
ScriptOrigin origin(filename, line_offset, column_offset, True(isolate));
265265

266-
Mutex::ScopedLock lock(code_cache_mutex_);
267-
268266
ScriptCompiler::CachedData* cached_data = nullptr;
269267
{
268+
// Note: The lock here should not extend into the
269+
// `CompileFunctionInContext()` call below, because this function may
270+
// recurse if there is a syntax error during bootstrap (because the fatal
271+
// exception handler is invoked, which may load built-in modules).
272+
Mutex::ScopedLock lock(code_cache_mutex_);
270273
auto cache_it = code_cache_.find(id);
271274
if (cache_it != code_cache_.end()) {
272275
// Transfer ownership to ScriptCompiler::Source later.
@@ -313,8 +316,13 @@ MaybeLocal<Function> NativeModuleLoader::LookupAndCompile(
313316
ScriptCompiler::CreateCodeCacheForFunction(fun));
314317
CHECK_NOT_NULL(new_cached_data);
315318

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

319327
return scope.Escape(fun);
320328
}

0 commit comments

Comments
 (0)