Call FlushFileBuffers on output files.
There is a latent Windows kernel bug, the exact trigger
conditions are not well understood, which can cause a file
to be correctly written, but unable to be correctly read.
The workaround appears to be simply calling FlushFileBuffers.
Differential Revision: https://reviews.llvm.org/D42925
llvm-svn: 325274
diff --git a/llvm/lib/Support/Windows/Path.inc b/llvm/lib/Support/Windows/Path.inc
index f81790b..58c555d 100644
--- a/llvm/lib/Support/Windows/Path.inc
+++ b/llvm/lib/Support/Windows/Path.inc
@@ -822,6 +822,8 @@
std::error_code mapped_file_region::init(int FD, uint64_t Offset,
mapmode Mode) {
+ this->FD = FD;
+ this->Mode = Mode;
HANDLE FileHandle = reinterpret_cast<HANDLE>(_get_osfhandle(FD));
if (FileHandle == INVALID_HANDLE_VALUE)
return make_error_code(errc::bad_file_descriptor);
@@ -887,8 +889,20 @@
}
mapped_file_region::~mapped_file_region() {
- if (Mapping)
+ if (Mapping) {
::UnmapViewOfFile(Mapping);
+
+ if (Mode == mapmode::readwrite) {
+ // There is a Windows kernel bug, the exact trigger conditions of which
+ // are not well understood. When triggered, dirty pages are not properly
+ // flushed and subsequent process's attempts to read a file can return
+ // invalid data. Calling FlushFileBuffers on the write handle is
+ // sufficient to ensure that this bug is not triggered.
+ HANDLE FileHandle = reinterpret_cast<HANDLE>(_get_osfhandle(FD));
+ if (FileHandle != INVALID_HANDLE_VALUE)
+ ::FlushFileBuffers(FileHandle);
+ }
+ }
}
size_t mapped_file_region::size() const {