Skip to content

Commit 733f65c

Browse files
author
Salinas, David
authored
Modify the localCache API to require an explicit commit on CachedFile… (llvm#887)
2 parents 9792620 + 0bccfcd commit 733f65c

File tree

7 files changed

+53
-13
lines changed

7 files changed

+53
-13
lines changed

lldb/source/Core/DataFileCache.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,11 @@ bool DataFileCache::SetCachedData(llvm::StringRef key,
132132
if (file_or_err) {
133133
llvm::CachedFileStream *cfs = file_or_err->get();
134134
cfs->OS->write((const char *)data.data(), data.size());
135+
if (llvm::Error err = cfs->commit()) {
136+
Log *log = GetLog(LLDBLog::Modules);
137+
LLDB_LOG_ERROR(log, std::move(err),
138+
"failed to commit to the cache for key: {0}");
139+
}
135140
return true;
136141
} else {
137142
Log *log = GetLog(LLDBLog::Modules);

llvm/include/llvm/Support/Caching.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class CachedFileStream {
3030
CachedFileStream(std::unique_ptr<raw_pwrite_stream> OS,
3131
std::string OSPath = "")
3232
: OS(std::move(OS)), ObjectPathName(OSPath) {}
33+
virtual Error commit() { return Error::success(); }
3334
std::unique_ptr<raw_pwrite_stream> OS;
3435
std::string ObjectPathName;
3536
virtual ~CachedFileStream() = default;

llvm/lib/Debuginfod/Debuginfod.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ class StreamedHTTPResponseHandler : public HTTPResponseHandler {
188188
public:
189189
StreamedHTTPResponseHandler(CreateStreamFn CreateStream, HTTPClient &Client)
190190
: CreateStream(CreateStream), Client(Client) {}
191+
Error commit();
191192
virtual ~StreamedHTTPResponseHandler() = default;
192193

193194
Error handleBodyChunk(StringRef BodyChunk) override;
@@ -210,6 +211,12 @@ Error StreamedHTTPResponseHandler::handleBodyChunk(StringRef BodyChunk) {
210211
return Error::success();
211212
}
212213

214+
Error StreamedHTTPResponseHandler::commit() {
215+
if (FileStream)
216+
return FileStream->commit();
217+
return Error::success();
218+
}
219+
213220
// An over-accepting simplification of the HTTP RFC 7230 spec.
214221
static bool isHeader(StringRef S) {
215222
StringRef Name;
@@ -298,6 +305,8 @@ Expected<std::string> getCachedOrDownloadArtifact(
298305
Error Err = Client.perform(Request, Handler);
299306
if (Err)
300307
return std::move(Err);
308+
if (Err = Handler.commit())
309+
return std::move(Err);
301310

302311
unsigned Code = Client.responseCode();
303312
if (Code && Code != 200)

llvm/lib/LTO/LTOBackend.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,9 @@ static void codegen(const CodegenConfig &Conf, TargetMachine *TM,
477477

478478
if (DwoOut)
479479
DwoOut->keep();
480+
481+
if (Error Err = Stream->commit())
482+
report_fatal_error(std::move(Err));
480483
}
481484

482485
static void splitCodeGen(const CodegenConfig &CodegenC, TargetMachine *TM,

llvm/lib/Support/Caching.cpp

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ Expected<FileCache> llvm::localCache(const Twine &CacheNameRef,
8080
sys::fs::TempFile TempFile;
8181
std::string ModuleName;
8282
unsigned Task;
83+
bool Committed = false;
8384

8485
CacheStream(std::unique_ptr<raw_pwrite_stream> OS, AddBufferFn AddBuffer,
8586
sys::fs::TempFile TempFile, std::string EntryPath,
@@ -88,9 +89,10 @@ Expected<FileCache> llvm::localCache(const Twine &CacheNameRef,
8889
AddBuffer(std::move(AddBuffer)), TempFile(std::move(TempFile)),
8990
ModuleName(ModuleName), Task(Task) {}
9091

91-
~CacheStream() {
92-
// TODO: Manually commit rather than using non-trivial destructor,
93-
// allowing to replace report_fatal_errors with a return Error.
92+
Error commit() override {
93+
if (Committed)
94+
return Error::success();
95+
Committed = true;
9496

9597
// Make sure the stream is closed before committing it.
9698
OS.reset();
@@ -100,10 +102,12 @@ Expected<FileCache> llvm::localCache(const Twine &CacheNameRef,
100102
MemoryBuffer::getOpenFile(
101103
sys::fs::convertFDToNativeFile(TempFile.FD), ObjectPathName,
102104
/*FileSize=*/-1, /*RequiresNullTerminator=*/false);
103-
if (!MBOrErr)
104-
report_fatal_error(Twine("Failed to open new cache file ") +
105-
TempFile.TmpName + ": " +
106-
MBOrErr.getError().message() + "\n");
105+
if (!MBOrErr) {
106+
std::error_code EC = MBOrErr.getError();
107+
return createStringError(EC, Twine("Failed to open new cache file ") +
108+
TempFile.TmpName + ": " +
109+
EC.message() + "\n");
110+
}
107111

108112
// On POSIX systems, this will atomically replace the destination if
109113
// it already exists. We try to emulate this on Windows, but this may
@@ -118,7 +122,10 @@ Expected<FileCache> llvm::localCache(const Twine &CacheNameRef,
118122
E = handleErrors(std::move(E), [&](const ECError &E) -> Error {
119123
std::error_code EC = E.convertToErrorCode();
120124
if (EC != errc::permission_denied)
121-
return errorCodeToError(EC);
125+
return createStringError(
126+
EC, Twine("Failed to rename temporary file ") +
127+
TempFile.TmpName + " to " + ObjectPathName + ": " +
128+
EC.message() + "\n");
122129

123130
auto MBCopy = MemoryBuffer::getMemBufferCopy((*MBOrErr)->getBuffer(),
124131
ObjectPathName);
@@ -131,11 +138,22 @@ Expected<FileCache> llvm::localCache(const Twine &CacheNameRef,
131138
});
132139

133140
if (E)
134-
report_fatal_error(Twine("Failed to rename temporary file ") +
135-
TempFile.TmpName + " to " + ObjectPathName + ": " +
136-
toString(std::move(E)) + "\n");
141+
return E;
137142

138143
AddBuffer(Task, ModuleName, std::move(*MBOrErr));
144+
return Error::success();
145+
}
146+
147+
~CacheStream() {
148+
// In Debug builds, try to track down places where commit() was not
149+
// called before destruction.
150+
assert(Committed);
151+
// In Release builds, fall back to the previous behaviour of committing
152+
// during destruction and reporting errors with report_fatal_error.
153+
if (Committed)
154+
return;
155+
if (Error Err = commit())
156+
report_fatal_error(Twine(toString(std::move(Err))));
139157
}
140158
};
141159

llvm/tools/gold/gold-plugin.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1119,7 +1119,9 @@ static std::vector<std::pair<SmallString<128>, bool>> runLTO() {
11191119

11201120
auto AddBuffer = [&](size_t Task, const Twine &moduleName,
11211121
std::unique_ptr<MemoryBuffer> MB) {
1122-
*AddStream(Task, moduleName)->OS << MB->getBuffer();
1122+
auto Stream = *AddStream(Task, ModuleName);
1123+
Stream->OS << MB->getBuffer();
1124+
check(Stream->commit(), "Failed to commit cache");
11231125
};
11241126

11251127
FileCache Cache;

llvm/tools/llvm-lto2/llvm-lto2.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,9 @@ static int run(int argc, char **argv) {
448448

449449
auto AddBuffer = [&](size_t Task, const Twine &ModuleName,
450450
std::unique_ptr<MemoryBuffer> MB) {
451-
*AddStream(Task, ModuleName)->OS << MB->getBuffer();
451+
auto Stream = AddStream(Task, ModuleName);
452+
*Stream->OS << MB->getBuffer();
453+
check(Stream->commit(), "Failed to commit cache");
452454
};
453455

454456
FileCache Cache;

0 commit comments

Comments
 (0)