Skip to content

Commit 0791cb7

Browse files
authored
Merge pull request #6187 from akyrtzi/pr/stable2/cas-fix-db-create-race-issue
[stable/20221013][CAS/LazyMappedFileRegion] Fix racing issue during the initial creation of a database file
2 parents 20a4da9 + 4f88b35 commit 0791cb7

File tree

8 files changed

+331
-39
lines changed

8 files changed

+331
-39
lines changed

llvm/include/llvm/CAS/LazyMappedFileRegion.h

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,6 @@ class LazyMappedFileRegion {
7070
/// and/or update callers not to rely on this.
7171
StringRef getPath() const { return Path; }
7272

73-
char *data() const { return Map.data(); }
74-
7573
/// Resize to at least \p MinSize.
7674
///
7775
/// Errors if \p MinSize is bigger than \a capacity() or if the operation
@@ -86,10 +84,18 @@ class LazyMappedFileRegion {
8684
/// Size allocated on disk.
8785
size_t size() const { return CachedSize; }
8886

87+
#ifdef _WIN32
88+
char *data() const { return VM; }
89+
/// Size of the underlying \a mapped_file_region. This cannot be extended.
90+
size_t capacity() const { return MaxSize; }
91+
explicit operator bool() const { return VM; }
92+
#else
93+
char *data() const { return Map.data(); }
8994
/// Size of the underlying \a mapped_file_region. This cannot be extended.
9095
size_t capacity() const { return Map.size(); }
91-
9296
explicit operator bool() const { return bool(Map); }
97+
#endif
98+
9399

94100
~LazyMappedFileRegion() { destroyImpl(); }
95101

@@ -106,27 +112,34 @@ class LazyMappedFileRegion {
106112

107113
private:
108114
Error extendSizeImpl(uint64_t MinSize);
109-
void destroyImpl() {
110-
if (FD) {
111-
sys::fs::closeFile(*FD);
112-
FD = None;
113-
}
114-
}
115+
void destroyImpl();
115116
void moveImpl(LazyMappedFileRegion &RHS) {
116117
Path = std::move(RHS.Path);
117118
FD = std::move(RHS.FD);
118-
RHS.FD = None;
119+
RHS.FD = std::nullopt;
120+
#ifdef _WIN32
121+
VM = RHS.VM;
122+
MaxSize = RHS.MaxSize;
123+
MappedRegions = RHS.MappedRegions;
124+
#else
119125
Map = std::move(RHS.Map);
126+
assert(!RHS.Map &&
127+
"Expected std::optional(std::optional&&) to clear RHS.Map");
128+
#endif
120129
CachedSize = RHS.CachedSize.load();
121130
RHS.CachedSize = 0;
122131
MaxSizeIncrement = RHS.MaxSizeIncrement;
123-
124-
assert(!RHS.Map && "Expected Optional(Optional&&) to clear RHS.Map");
125132
}
126133

127134
std::string Path;
128-
Optional<sys::fs::file_t> FD;
135+
std::optional<int> FD;
136+
#ifdef _WIN32
137+
char *VM = nullptr;
138+
uint64_t MaxSize = 0;
139+
std::vector<void*> MappedRegions;
140+
#else
129141
sys::fs::mapped_file_region Map;
142+
#endif
130143
std::atomic<uint64_t> CachedSize;
131144
std::mutex Mutex;
132145
uint64_t MaxSizeIncrement = 0;

llvm/include/llvm/Support/FileSystem.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1200,7 +1200,10 @@ std::error_code getRealPathFromHandle(file_t Handle,
12001200
/// Lock the file.
12011201
///
12021202
/// This function acts as @ref tryLockFile but it waits infinitely.
1203-
std::error_code lockFile(int FD);
1203+
/// \param FD file descriptor to use for locking.
1204+
/// \param Exclusive if \p true use exclusive/writer lock, otherwise use
1205+
/// shared/reader lock.
1206+
std::error_code lockFile(int FD, bool Exclusive = true);
12041207

12051208
/// Unlock the file.
12061209
///

0 commit comments

Comments
 (0)