Skip to content

Commit 7e46f5d

Browse files
[Support] Add mapped_file_region::sync(), equivalent to msync (#153632)
1 parent 769a905 commit 7e46f5d

File tree

4 files changed

+56
-0
lines changed

4 files changed

+56
-0
lines changed

llvm/include/llvm/Support/FileSystem.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1342,6 +1342,11 @@ class mapped_file_region {
13421342
LLVM_ABI size_t size() const;
13431343
LLVM_ABI char *data() const;
13441344

1345+
/// Write changes to disk and synchronize. Equivalent to POSIX msync. This
1346+
/// will wait for flushing memory-mapped region back to disk and can be very
1347+
/// slow.
1348+
LLVM_ABI std::error_code sync() const;
1349+
13451350
/// Get a const view of the data. Modifying this memory has undefined
13461351
/// behavior.
13471352
LLVM_ABI const char *const_data() const;

llvm/lib/Support/Unix/Path.inc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -876,6 +876,12 @@ void mapped_file_region::unmapImpl() {
876876
::munmap(Mapping, Size);
877877
}
878878

879+
std::error_code mapped_file_region::sync() const {
880+
if (int Res = ::msync(Mapping, Size, MS_SYNC))
881+
return std::error_code(Res, std::generic_category());
882+
return std::error_code();
883+
}
884+
879885
void mapped_file_region::dontNeedImpl() {
880886
assert(Mode == mapped_file_region::readonly);
881887
if (!Mapping)

llvm/lib/Support/Windows/Path.inc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,6 +1006,14 @@ void mapped_file_region::unmapImpl() {
10061006

10071007
void mapped_file_region::dontNeedImpl() {}
10081008

1009+
std::error_code mapped_file_region::sync() const {
1010+
if (!::FlushViewOfFile(Mapping, Size))
1011+
return mapWindowsError(GetLastError());
1012+
if (!::FlushFileBuffers(FileHandle))
1013+
return mapWindowsError(GetLastError());
1014+
return std::error_code();
1015+
}
1016+
10091017
int mapped_file_region::alignment() {
10101018
SYSTEM_INFO SysInfo;
10111019
::GetSystemInfo(&SysInfo);

llvm/unittests/Support/Path.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1471,6 +1471,43 @@ TEST_F(FileSystemTest, FileMapping) {
14711471
ASSERT_NO_ERROR(fs::remove(TempPath));
14721472
}
14731473

1474+
TEST_F(FileSystemTest, FileMappingSync) {
1475+
// Create a temp file.
1476+
SmallString<0> TempPath(TestDirectory);
1477+
sys::path::append(TempPath, "test-%%%%");
1478+
auto TempFileOrError = fs::TempFile::create(TempPath);
1479+
ASSERT_TRUE((bool)TempFileOrError);
1480+
fs::TempFile File = std::move(*TempFileOrError);
1481+
StringRef Content("hello there");
1482+
std::string FileName = File.TmpName;
1483+
ASSERT_NO_ERROR(
1484+
fs::resize_file_before_mapping_readwrite(File.FD, Content.size()));
1485+
{
1486+
// Map in the file and write some content.
1487+
std::error_code EC;
1488+
fs::mapped_file_region MFR(fs::convertFDToNativeFile(File.FD),
1489+
fs::mapped_file_region::readwrite,
1490+
Content.size(), 0, EC);
1491+
1492+
// Keep the file so it can be read.
1493+
ASSERT_FALSE((bool)File.keep());
1494+
1495+
// Write content through mapped memory.
1496+
ASSERT_NO_ERROR(EC);
1497+
std::copy(Content.begin(), Content.end(), MFR.data());
1498+
1499+
// Synchronize to file system.
1500+
ASSERT_FALSE((bool)MFR.sync());
1501+
1502+
// Check the file content using file IO APIs.
1503+
auto Buffer = MemoryBuffer::getFile(FileName);
1504+
ASSERT_TRUE((bool)Buffer);
1505+
ASSERT_EQ(Content, Buffer->get()->getBuffer());
1506+
}
1507+
// Manually remove the test file.
1508+
ASSERT_FALSE((bool)fs::remove(FileName));
1509+
}
1510+
14741511
TEST(Support, NormalizePath) {
14751512
// Input, Expected Win, Expected Posix
14761513
using TestTuple = std::tuple<const char *, const char *, const char *>;

0 commit comments

Comments
 (0)