[llvm] [CAS] Give Windows file mappings names to better ensure same mappings are used (PR #190692)
Hiroshi Yamauchi via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 6 19:14:47 PDT 2026
https://github.com/hjyamauchi updated https://github.com/llvm/llvm-project/pull/190692
>From 8f92906f05bcd0c21bdc704ad25742b5f8f1f561 Mon Sep 17 00:00:00 2001
From: Hiroshi Yamauchi <hjyamauchi at gmail.com>
Date: Mon, 6 Apr 2026 14:49:31 -0700
Subject: [PATCH] [CAS] Give Windows file mappings names to better ensure same
mappings are used
---
llvm/include/llvm/Support/FileSystem.h | 5 ++--
llvm/lib/CAS/MappedFileRegionArena.cpp | 11 ++++++++-
llvm/lib/Support/Unix/Path.inc | 9 ++++---
llvm/lib/Support/Windows/Path.inc | 17 +++++++++----
llvm/unittests/Support/Path.cpp | 34 ++++++++++++++++++++++++++
5 files changed, 64 insertions(+), 12 deletions(-)
diff --git a/llvm/include/llvm/Support/FileSystem.h b/llvm/include/llvm/Support/FileSystem.h
index 38b801dffeb29..8dd5bb86949fa 100644
--- a/llvm/include/llvm/Support/FileSystem.h
+++ b/llvm/include/llvm/Support/FileSystem.h
@@ -1335,7 +1335,7 @@ class mapped_file_region {
LLVM_ABI void willNeedImpl();
LLVM_ABI std::error_code init(sys::fs::file_t FD, uint64_t Offset,
- mapmode Mode);
+ mapmode Mode, const char *Name);
public:
mapped_file_region() = default;
@@ -1351,7 +1351,8 @@ class mapped_file_region {
/// \param fd An open file descriptor to map. Does not take ownership of fd.
LLVM_ABI mapped_file_region(sys::fs::file_t fd, mapmode mode, size_t length,
- uint64_t offset, std::error_code &ec);
+ uint64_t offset, std::error_code &ec,
+ const char *name = nullptr);
~mapped_file_region() { unmapImpl(); }
diff --git a/llvm/lib/CAS/MappedFileRegionArena.cpp b/llvm/lib/CAS/MappedFileRegionArena.cpp
index 2dae3f2d05116..5712edaa629b0 100644
--- a/llvm/lib/CAS/MappedFileRegionArena.cpp
+++ b/llvm/lib/CAS/MappedFileRegionArena.cpp
@@ -252,8 +252,17 @@ Expected<MappedFileRegionArena> MappedFileRegionArena::create(
// Create the mapped region.
{
std::error_code EC;
+ const char *Name = nullptr;
+#ifdef _WIN32
+ // Give the file mapping a name to ensure the same mappings are
+ // shared across processes.
+ std::string MapName = Result.Path;
+ std::replace(MapName.begin(), MapName.end(), '\\', '/');
+ MapName = "Local\\" + MapName;
+ Name = MapName.c_str();
+#endif
sys::fs::mapped_file_region Map(
- File, sys::fs::mapped_file_region::readwrite, Capacity, 0, EC);
+ File, sys::fs::mapped_file_region::readwrite, Capacity, 0, EC, Name);
if (EC)
return createFileError(Result.Path, EC);
Result.Region = std::move(Map);
diff --git a/llvm/lib/Support/Unix/Path.inc b/llvm/lib/Support/Unix/Path.inc
index 057276f9b7eb2..3ed56ef01ac92 100644
--- a/llvm/lib/Support/Unix/Path.inc
+++ b/llvm/lib/Support/Unix/Path.inc
@@ -860,8 +860,8 @@ std::error_code setLastAccessAndModificationTime(int FD, TimePoint<> AccessTime,
#endif
}
-std::error_code mapped_file_region::init(int FD, uint64_t Offset,
- mapmode Mode) {
+std::error_code mapped_file_region::init(int FD, uint64_t Offset, mapmode Mode,
+ const char *Name) {
assert(Size != 0);
int flags = (Mode == readwrite) ? MAP_SHARED : MAP_PRIVATE;
@@ -896,12 +896,13 @@ std::error_code mapped_file_region::init(int FD, uint64_t Offset,
}
mapped_file_region::mapped_file_region(int fd, mapmode mode, size_t length,
- uint64_t offset, std::error_code &ec)
+ uint64_t offset, std::error_code &ec,
+ const char *name)
: Size(length), Mode(mode) {
sandbox::violationIfEnabled();
(void)Mode;
- ec = init(fd, offset, mode);
+ ec = init(fd, offset, mode, name);
if (ec)
copyFrom(mapped_file_region());
}
diff --git a/llvm/lib/Support/Windows/Path.inc b/llvm/lib/Support/Windows/Path.inc
index 48825a2de4993..5a70a030adf73 100644
--- a/llvm/lib/Support/Windows/Path.inc
+++ b/llvm/lib/Support/Windows/Path.inc
@@ -1030,7 +1030,8 @@ std::error_code setLastAccessAndModificationTime(int FD, TimePoint<> AccessTime,
}
std::error_code mapped_file_region::init(sys::fs::file_t OrigFileHandle,
- uint64_t Offset, mapmode Mode) {
+ uint64_t Offset, mapmode Mode,
+ const char *Name) {
this->Mode = Mode;
if (OrigFileHandle == INVALID_HANDLE_VALUE)
return make_error_code(errc::bad_file_descriptor);
@@ -1048,8 +1049,14 @@ std::error_code mapped_file_region::init(sys::fs::file_t OrigFileHandle,
break;
}
- HANDLE FileMappingHandle = ::CreateFileMappingW(OrigFileHandle, 0, flprotect,
- Hi_32(Size), Lo_32(Size), 0);
+ SmallVector<wchar_t, 128> NameUTF16;
+ if (Name)
+ if (std::error_code EC = UTF8ToUTF16(Name, NameUTF16))
+ return EC;
+
+ HANDLE FileMappingHandle =
+ ::CreateFileMappingW(OrigFileHandle, 0, flprotect, Hi_32(Size),
+ Lo_32(Size), Name ? c_str(NameUTF16) : 0);
if (FileMappingHandle == NULL) {
std::error_code ec = mapWindowsError(GetLastError());
return ec;
@@ -1106,11 +1113,11 @@ std::error_code mapped_file_region::init(sys::fs::file_t OrigFileHandle,
mapped_file_region::mapped_file_region(sys::fs::file_t fd, mapmode mode,
size_t length, uint64_t offset,
- std::error_code &ec)
+ std::error_code &ec, const char *name)
: Size(length) {
sandbox::violationIfEnabled();
- ec = init(fd, offset, mode);
+ ec = init(fd, offset, mode, name);
if (ec)
copyFrom(mapped_file_region());
}
diff --git a/llvm/unittests/Support/Path.cpp b/llvm/unittests/Support/Path.cpp
index ad3e6dc80cca4..b6bfaa93bd08c 100644
--- a/llvm/unittests/Support/Path.cpp
+++ b/llvm/unittests/Support/Path.cpp
@@ -1657,6 +1657,40 @@ TEST_F(FileSystemTest, FileMappingSync) {
ASSERT_FALSE((bool)fs::remove(FileName));
}
+#ifdef _WIN32
+TEST_F(FileSystemTest, FileMappingNamed) {
+ // Create a temp file.
+ SmallString<0> TempPath(TestDirectory);
+ sys::path::append(TempPath, "test-%%%%");
+ auto TempFileOrError = fs::TempFile::create(TempPath);
+ ASSERT_TRUE((bool)TempFileOrError);
+ fs::TempFile File = std::move(*TempFileOrError);
+ StringRef Content("hello there");
+ std::string FileName = File.TmpName;
+ ASSERT_NO_ERROR(
+ fs::resize_file_before_mapping_readwrite(File.FD, Content.size()));
+ {
+ // Map in the file twice with the same name
+ std::error_code EC1;
+ fs::mapped_file_region MFR1(
+ fs::convertFDToNativeFile(File.FD), fs::mapped_file_region::readwrite,
+ Content.size(), 0, EC1, "Local\\FileSystemTest_map");
+ ASSERT_NO_ERROR(EC1);
+
+ std::error_code EC2;
+ fs::mapped_file_region MFR2(
+ fs::convertFDToNativeFile(File.FD), fs::mapped_file_region::readwrite,
+ Content.size(), 0, EC2, "Local\\FileSystemTest_map");
+ ASSERT_NO_ERROR(EC2);
+
+ // Write content through mapped memory and check the content
+ llvm::copy(Content, MFR1.data());
+ ASSERT_EQ(std::memcmp(MFR1.data(), MFR2.data(), Content.size()), 0);
+ }
+ ASSERT_FALSE((bool)File.discard());
+}
+#endif
+
TEST(Support, NormalizePath) {
// Input, Expected Win, Expected Posix
using TestTuple = std::tuple<const char *, const char *, const char *>;
More information about the llvm-commits
mailing list