Skip to content

Commit 88b5bbd

Browse files
committed
[Support] Return LockFileManager errors right away
1 parent c40f0fe commit 88b5bbd

File tree

5 files changed

+59
-125
lines changed

5 files changed

+59
-125
lines changed

clang/lib/Frontend/CompilerInstance.cpp

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1477,29 +1477,28 @@ static bool compileModuleAndReadASTBehindLock(
14771477
llvm::sys::fs::create_directories(Dir);
14781478

14791479
while (true) {
1480-
llvm::LockFileManager Locked(ModuleFileName);
1481-
switch (Locked) {
1482-
case llvm::LockFileManager::LFS_Error:
1480+
llvm::LockFileManager Lock(ModuleFileName);
1481+
bool Owned;
1482+
if (llvm::Error Err = Lock.tryLock().moveInto(Owned)) {
14831483
// ModuleCache takes care of correctness and locks are only necessary for
14841484
// performance. Fallback to building the module in case of any lock
14851485
// related errors.
14861486
Diags.Report(ModuleNameLoc, diag::remark_module_lock_failure)
1487-
<< Module->Name << Locked.getErrorMessage();
1487+
<< Module->Name << toString(std::move(Err));
14881488
// Clear out any potential leftover.
1489-
Locked.unsafeRemoveLockFile();
1490-
[[fallthrough]];
1491-
case llvm::LockFileManager::LFS_Owned:
1489+
Lock.unsafeRemoveLockFile();
1490+
return compileModuleAndReadASTImpl(ImportingInstance, ImportLoc,
1491+
ModuleNameLoc, Module, ModuleFileName);
1492+
}
1493+
if (Owned) {
14921494
// We're responsible for building the module ourselves.
14931495
return compileModuleAndReadASTImpl(ImportingInstance, ImportLoc,
14941496
ModuleNameLoc, Module, ModuleFileName);
1495-
1496-
case llvm::LockFileManager::LFS_Shared:
1497-
break; // The interesting case.
14981497
}
14991498

15001499
// Someone else is responsible for building the module. Wait for them to
15011500
// finish.
1502-
switch (Locked.waitForUnlock()) {
1501+
switch (Lock.waitForUnlock()) {
15031502
case llvm::LockFileManager::Res_Success:
15041503
break; // The interesting case.
15051504
case llvm::LockFileManager::Res_OwnerDied:
@@ -1511,7 +1510,7 @@ static bool compileModuleAndReadASTBehindLock(
15111510
Diags.Report(ModuleNameLoc, diag::remark_module_lock_timeout)
15121511
<< Module->Name;
15131512
// Clear the lock file so that future invocations can make progress.
1514-
Locked.unsafeRemoveLockFile();
1513+
Lock.unsafeRemoveLockFile();
15151514
continue;
15161515
}
15171516

clang/lib/Serialization/GlobalModuleIndex.cpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -849,22 +849,21 @@ GlobalModuleIndex::writeIndex(FileManager &FileMgr,
849849

850850
// Coordinate building the global index file with other processes that might
851851
// try to do the same.
852-
llvm::LockFileManager Locked(IndexPath);
853-
switch (Locked) {
854-
case llvm::LockFileManager::LFS_Error:
852+
llvm::LockFileManager Lock(IndexPath);
853+
bool Owned;
854+
if (llvm::Error Err = Lock.tryLock().moveInto(Owned)) {
855+
llvm::consumeError(std::move(Err));
855856
return llvm::createStringError(std::errc::io_error, "LFS error");
856-
857-
case llvm::LockFileManager::LFS_Owned:
858-
// We're responsible for building the index ourselves. Do so below.
859-
break;
860-
861-
case llvm::LockFileManager::LFS_Shared:
857+
}
858+
if (!Owned) {
862859
// Someone else is responsible for building the index. We don't care
863860
// when they finish, so we're done.
864861
return llvm::createStringError(std::errc::device_or_resource_busy,
865862
"someone else is building the index");
866863
}
867864

865+
// We're responsible for building the index ourselves.
866+
868867
// The module index builder.
869868
GlobalModuleIndexBuilder Builder(FileMgr, PCHContainerRdr);
870869

llvm/include/llvm/Support/LockFileManager.h

Lines changed: 5 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#define LLVM_SUPPORT_LOCKFILEMANAGER_H
1010

1111
#include "llvm/ADT/SmallString.h"
12+
#include "llvm/Support/Error.h"
1213
#include <optional>
1314
#include <system_error>
1415
#include <utility> // for std::pair
@@ -26,19 +27,6 @@ class StringRef;
2627
/// operation.
2728
class LockFileManager {
2829
public:
29-
/// Describes the state of a lock file.
30-
enum LockFileState {
31-
/// The lock file has been created and is owned by this instance
32-
/// of the object.
33-
LFS_Owned,
34-
/// The lock file already exists and is owned by some other
35-
/// instance.
36-
LFS_Shared,
37-
/// An error occurred while trying to create or find the lock
38-
/// file.
39-
LFS_Error
40-
};
41-
4230
/// Describes the result of waiting for the owner to release the lock.
4331
enum WaitForUnlockResult {
4432
/// The lock was released successfully.
@@ -55,8 +43,6 @@ class LockFileManager {
5543
SmallString<128> UniqueLockFileName;
5644

5745
std::optional<std::pair<std::string, int>> Owner;
58-
std::error_code ErrorCode;
59-
std::string ErrorDiagMsg;
6046

6147
LockFileManager(const LockFileManager &) = delete;
6248
LockFileManager &operator=(const LockFileManager &) = delete;
@@ -71,10 +57,10 @@ class LockFileManager {
7157
LockFileManager(StringRef FileName);
7258
~LockFileManager();
7359

74-
/// Determine the state of the lock file.
75-
LockFileState getState() const;
76-
77-
operator LockFileState() const { return getState(); }
60+
/// Tries to acquire the lock without blocking.
61+
/// \returns true if the lock was successfully acquired, false if the lock is
62+
/// already held by someone else, or \c Error in case of unexpected failure.
63+
Expected<bool> tryLock();
7864

7965
/// For a shared lock, wait until the owner releases the lock.
8066
/// Total timeout for the file to appear is ~1.5 minutes.
@@ -84,15 +70,6 @@ class LockFileManager {
8470
/// Remove the lock file. This may delete a different lock file than
8571
/// the one previously read if there is a race.
8672
std::error_code unsafeRemoveLockFile();
87-
88-
/// Get error message, or "" if there is no error.
89-
std::string getErrorMessage() const;
90-
91-
/// Set error and error message
92-
void setError(const std::error_code &EC, StringRef ErrorMsg = "") {
93-
ErrorCode = EC;
94-
ErrorDiagMsg = ErrorMsg.str();
95-
}
9673
};
9774

9875
} // end namespace llvm

llvm/lib/Support/LockFileManager.cpp

Lines changed: 27 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -157,42 +157,35 @@ class RemoveUniqueLockFileOnSignal {
157157

158158
} // end anonymous namespace
159159

160-
LockFileManager::LockFileManager(StringRef FileName)
161-
{
162-
this->FileName = FileName;
163-
if (std::error_code EC = sys::fs::make_absolute(this->FileName)) {
164-
std::string S("failed to obtain absolute path for ");
165-
S.append(std::string(this->FileName));
166-
setError(EC, S);
167-
return;
168-
}
169-
LockFileName = this->FileName;
160+
LockFileManager::LockFileManager(StringRef FileName) : FileName(FileName) {}
161+
162+
Expected<bool> LockFileManager::tryLock() {
163+
SmallString<128> AbsoluteFileName(FileName);
164+
if (std::error_code EC = sys::fs::make_absolute(AbsoluteFileName))
165+
return createStringError("failed to obtain absolute path for " +
166+
AbsoluteFileName);
167+
LockFileName = AbsoluteFileName;
170168
LockFileName += ".lock";
171169

172170
// If the lock file already exists, don't bother to try to create our own
173171
// lock file; it won't work anyway. Just figure out who owns this lock file.
174172
if ((Owner = readLockFile(LockFileName)))
175-
return;
173+
return false;
176174

177175
// Create a lock file that is unique to this instance.
178176
UniqueLockFileName = LockFileName;
179177
UniqueLockFileName += "-%%%%%%%%";
180178
int UniqueLockFileID;
181179
if (std::error_code EC = sys::fs::createUniqueFile(
182-
UniqueLockFileName, UniqueLockFileID, UniqueLockFileName)) {
183-
std::string S("failed to create unique file ");
184-
S.append(std::string(UniqueLockFileName));
185-
setError(EC, S);
186-
return;
187-
}
180+
UniqueLockFileName, UniqueLockFileID, UniqueLockFileName))
181+
return createStringError("failed to create unique file " +
182+
UniqueLockFileName);
188183

189184
// Write our process ID to our unique lock file.
190185
{
191186
SmallString<256> HostID;
192-
if (auto EC = getHostID(HostID)) {
193-
setError(EC, "failed to get host id");
194-
return;
195-
}
187+
if (auto EC = getHostID(HostID))
188+
return createStringError(EC, "failed to get host id");
196189

197190
raw_fd_ostream Out(UniqueLockFileID, /*shouldClose=*/true);
198191
Out << HostID << ' ' << sys::Process::getProcessId();
@@ -201,13 +194,12 @@ LockFileManager::LockFileManager(StringRef FileName)
201194
if (Out.has_error()) {
202195
// We failed to write out PID, so report the error, remove the
203196
// unique lock file, and fail.
204-
std::string S("failed to write to ");
205-
S.append(std::string(UniqueLockFileName));
206-
setError(Out.error(), S);
197+
Error Err = createStringError(Out.error(),
198+
"failed to write to " + UniqueLockFileName);
207199
sys::fs::remove(UniqueLockFileName);
208200
// Don't call report_fatal_error.
209201
Out.clear_error();
210-
return;
202+
return std::move(Err);
211203
}
212204
}
213205

@@ -221,23 +213,19 @@ LockFileManager::LockFileManager(StringRef FileName)
221213
sys::fs::create_link(UniqueLockFileName, LockFileName);
222214
if (!EC) {
223215
RemoveUniqueFile.lockAcquired();
224-
return;
216+
return true;
225217
}
226218

227-
if (EC != errc::file_exists) {
228-
std::string S("failed to create link ");
229-
raw_string_ostream OSS(S);
230-
OSS << LockFileName.str() << " to " << UniqueLockFileName.str();
231-
setError(EC, S);
232-
return;
233-
}
219+
if (EC != errc::file_exists)
220+
return createStringError(EC, "failed to create link " + LockFileName +
221+
" to " + UniqueLockFileName);
234222

235223
// Someone else managed to create the lock file first. Read the process ID
236224
// from the lock file.
237225
if ((Owner = readLockFile(LockFileName))) {
238226
// Wipe out our unique lock file (it's useless now)
239227
sys::fs::remove(UniqueLockFileName);
240-
return;
228+
return false;
241229
}
242230

243231
if (!sys::fs::exists(LockFileName)) {
@@ -248,39 +236,14 @@ LockFileManager::LockFileManager(StringRef FileName)
248236

249237
// There is a lock file that nobody owns; try to clean it up and get
250238
// ownership.
251-
if ((EC = sys::fs::remove(LockFileName))) {
252-
std::string S("failed to remove lockfile ");
253-
S.append(std::string(UniqueLockFileName));
254-
setError(EC, S);
255-
return;
256-
}
257-
}
258-
}
259-
260-
LockFileManager::LockFileState LockFileManager::getState() const {
261-
if (Owner)
262-
return LFS_Shared;
263-
264-
if (ErrorCode)
265-
return LFS_Error;
266-
267-
return LFS_Owned;
268-
}
269-
270-
std::string LockFileManager::getErrorMessage() const {
271-
if (ErrorCode) {
272-
std::string Str(ErrorDiagMsg);
273-
std::string ErrCodeMsg = ErrorCode.message();
274-
raw_string_ostream OSS(Str);
275-
if (!ErrCodeMsg.empty())
276-
OSS << ": " << ErrCodeMsg;
277-
return Str;
239+
if ((EC = sys::fs::remove(LockFileName)))
240+
return createStringError(EC, "failed to remove lockfile " +
241+
UniqueLockFileName);
278242
}
279-
return "";
280243
}
281244

282245
LockFileManager::~LockFileManager() {
283-
if (getState() != LFS_Owned)
246+
if (Owner)
284247
return;
285248

286249
// Since we own the lock, remove the lock file and our own unique lock file.
@@ -293,7 +256,7 @@ LockFileManager::~LockFileManager() {
293256

294257
LockFileManager::WaitForUnlockResult
295258
LockFileManager::waitForUnlock(const unsigned MaxSeconds) {
296-
if (getState() != LFS_Shared)
259+
if (!Owner)
297260
return Res_Success;
298261

299262
// Since we don't yet have an event-based method to wait for the lock file,

llvm/lib/Target/AMDGPU/AMDGPUSplitModule.cpp

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1545,18 +1545,16 @@ PreservedAnalyses AMDGPUSplitModulePass::run(Module &M,
15451545
<< "'\n");
15461546

15471547
while (true) {
1548-
llvm::LockFileManager Locked(LockFilePath.str());
1549-
switch (Locked) {
1550-
case LockFileManager::LFS_Error:
1548+
llvm::LockFileManager Lock(LockFilePath.str());
1549+
bool Owned;
1550+
if (Error Err = Lock.tryLock().moveInto(Owned)) {
1551+
consumeError(std::move(Err));
15511552
LLVM_DEBUG(
15521553
dbgs() << "[amdgpu-split-module] unable to acquire lockfile, debug "
15531554
"output may be mangled by other processes\n");
1554-
Locked.unsafeRemoveLockFile();
1555-
break;
1556-
case LockFileManager::LFS_Owned:
1557-
break;
1558-
case LockFileManager::LFS_Shared: {
1559-
switch (Locked.waitForUnlock()) {
1555+
Lock.unsafeRemoveLockFile();
1556+
} else if (!Owned) {
1557+
switch (Lock.waitForUnlock()) {
15601558
case LockFileManager::Res_Success:
15611559
break;
15621560
case LockFileManager::Res_OwnerDied:
@@ -1566,11 +1564,9 @@ PreservedAnalyses AMDGPUSplitModulePass::run(Module &M,
15661564
dbgs()
15671565
<< "[amdgpu-split-module] unable to acquire lockfile, debug "
15681566
"output may be mangled by other processes\n");
1569-
Locked.unsafeRemoveLockFile();
1567+
Lock.unsafeRemoveLockFile();
15701568
break; // give up
15711569
}
1572-
break;
1573-
}
15741570
}
15751571

15761572
splitAMDGPUModule(TTIGetter, M, N, ModuleCallback);

0 commit comments

Comments
 (0)