ModuleInterface: lock .swiftinterface while generating module cache

This ensures only one process is generating module cache from an interface
file so that we don't blow up memory usage when multiple processes are
doing the same. The locking mechanism is similar to that of Clang's.

A better approach is that the build system takes care of the module building
step as a formal dependency.

rdar://52839445
This commit is contained in:
Xi Ge
2020-01-09 13:27:20 -08:00
parent 93d07c6c30
commit 8dda0193a6
5 changed files with 97 additions and 7 deletions

View File

@@ -950,13 +950,11 @@ class ModuleInterfaceLoaderImpl {
std::unique_ptr<llvm::MemoryBuffer> moduleBuffer;
// We didn't discover a module corresponding to this interface.
// Diagnose that we didn't find a loadable module, if we were asked to.
if (remarkOnRebuildFromInterface) {
auto remarkRebuild = [&]() {
rebuildInfo.diagnose(ctx, diagnosticLoc, moduleName,
interfacePath);
}
};
// If we found an out-of-date .swiftmodule, we still want to add it as
// a dependency of the .swiftinterface. That way if it's updated, but
// the .swiftinterface remains the same, we invalidate the cache and
@@ -966,7 +964,9 @@ class ModuleInterfaceLoaderImpl {
builder.addExtraDependency(modulePath);
if (builder.buildSwiftModule(cachedOutputPath, /*shouldSerializeDeps*/true,
&moduleBuffer))
&moduleBuffer,
remarkOnRebuildFromInterface ? remarkRebuild:
llvm::function_ref<void()>()))
return std::make_error_code(std::errc::invalid_argument);
assert(moduleBuffer &&