Skip to content

Commit 46660c1

Browse files
committed
Address more review feedback.
1 parent d4cd9ea commit 46660c1

File tree

4 files changed

+73
-14
lines changed

4 files changed

+73
-14
lines changed

llvm/include/llvm/Support/Caching.h

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,32 @@ class MemoryBuffer;
2424
/// This class wraps an output stream for a file. Most clients should just be
2525
/// able to return an instance of this base class from the stream callback, but
2626
/// if a client needs to perform some action after the stream is written to,
27-
/// that can be done by deriving from this class and overriding the destructor.
27+
/// that can be done by deriving from this class and overriding the destructor
28+
/// or the commit() method.
2829
class CachedFileStream {
2930
public:
3031
CachedFileStream(std::unique_ptr<raw_pwrite_stream> OS,
3132
std::string OSPath = "")
3233
: OS(std::move(OS)), ObjectPathName(OSPath) {}
33-
virtual Error commit() { return Error::success(); }
34+
35+
/// Must be called exactly once after the writes to OS have been completed
36+
/// but before the CachedFileStream object is destroyed.
37+
virtual Error commit() {
38+
if (Committed)
39+
return createStringError(make_error_code(std::errc::invalid_argument),
40+
Twine("CacheStream already committed."));
41+
Committed = true;
42+
43+
return Error::success();
44+
}
45+
46+
bool Committed = false;
3447
std::unique_ptr<raw_pwrite_stream> OS;
3548
std::string ObjectPathName;
36-
virtual ~CachedFileStream() = default;
49+
virtual ~CachedFileStream() {
50+
if (!Committed)
51+
report_fatal_error("CachedFileStream was not committed.\n");
52+
}
3753
};
3854

3955
/// This type defines the callback to add a file that is generated on the fly.

llvm/lib/Debuginfod/Debuginfod.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,11 @@ class StreamedHTTPResponseHandler : public HTTPResponseHandler {
188188
public:
189189
StreamedHTTPResponseHandler(CreateStreamFn CreateStream, HTTPClient &Client)
190190
: CreateStream(CreateStream), Client(Client) {}
191+
192+
/// Must be called exactly once after the writes have been completed
193+
/// but before the StreamedHTTPResponseHandler object is destroyed.
191194
Error commit();
195+
192196
virtual ~StreamedHTTPResponseHandler() = default;
193197

194198
Error handleBodyChunk(StringRef BodyChunk) override;

llvm/lib/Support/Caching.cpp

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

8584
CacheStream(std::unique_ptr<raw_pwrite_stream> OS, AddBufferFn AddBuffer,
8685
sys::fs::TempFile TempFile, std::string EntryPath,
@@ -90,10 +89,9 @@ Expected<FileCache> llvm::localCache(const Twine &CacheNameRef,
9089
ModuleName(ModuleName), Task(Task) {}
9190

9291
Error commit() override {
93-
if (Committed)
94-
return createStringError(make_error_code(std::errc::invalid_argument),
95-
Twine("CacheStream already committed."));
96-
Committed = true;
92+
Error E = CachedFileStream::commit();
93+
if (E)
94+
return E;
9795

9896
// Make sure the stream is closed before committing it.
9997
OS.reset();
@@ -119,7 +117,7 @@ Expected<FileCache> llvm::localCache(const Twine &CacheNameRef,
119117
// AddBuffer a copy of the bytes we wrote in that case. We do this
120118
// instead of just using the existing file, because the pruner might
121119
// delete the file before we get a chance to use it.
122-
Error E = TempFile.keep(ObjectPathName);
120+
E = TempFile.keep(ObjectPathName);
123121
E = handleErrors(std::move(E), [&](const ECError &E) -> Error {
124122
std::error_code EC = E.convertToErrorCode();
125123
if (EC != errc::permission_denied)
@@ -144,11 +142,6 @@ Expected<FileCache> llvm::localCache(const Twine &CacheNameRef,
144142
AddBuffer(Task, ModuleName, std::move(*MBOrErr));
145143
return Error::success();
146144
}
147-
148-
~CacheStream() {
149-
if (!Committed)
150-
report_fatal_error("CacheStream was not committed.\n");
151-
}
152145
};
153146

154147
return [=](size_t Task, const Twine &ModuleName)

llvm/unittests/Support/Caching.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,3 +115,49 @@ TEST(Caching, WriteAfterCommit) {
115115

116116
ASSERT_NO_ERROR(sys::fs::remove_directories(CacheDir.str()));
117117
}
118+
119+
TEST(Caching, NoCommit) {
120+
SmallString<256> TempDir;
121+
sys::path::system_temp_directory(true, TempDir);
122+
SmallString<256> CacheDir;
123+
sys::path::append(CacheDir, TempDir, "llvm_test_cache");
124+
125+
sys::fs::remove_directories(CacheDir.str());
126+
127+
std::unique_ptr<MemoryBuffer> CachedBuffer;
128+
auto AddBuffer = [&CachedBuffer](unsigned Task, const Twine &ModuleName,
129+
std::unique_ptr<MemoryBuffer> M) {
130+
CachedBuffer = std::move(M);
131+
};
132+
auto CacheOrErr =
133+
localCache("LLVMTestCache", "LLVMTest", CacheDir, AddBuffer);
134+
ASSERT_TRUE(bool(CacheOrErr));
135+
136+
FileCache &Cache = *CacheOrErr;
137+
138+
auto AddStreamOrErr = Cache(1, "foo", "");
139+
ASSERT_TRUE(bool(AddStreamOrErr));
140+
141+
AddStreamFn &AddStream = *AddStreamOrErr;
142+
ASSERT_TRUE(AddStream);
143+
144+
auto FileOrErr = AddStream(1, "");
145+
ASSERT_TRUE(bool(FileOrErr));
146+
147+
CachedFileStream *CFS = FileOrErr->get();
148+
(*CFS->OS).write(data, sizeof(data));
149+
ASSERT_THAT_ERROR(CFS->commit(), Succeeded());
150+
151+
EXPECT_DEATH(
152+
{
153+
auto FileOrErr = AddStream(1, "");
154+
ASSERT_TRUE(bool(FileOrErr));
155+
156+
CachedFileStream *CFS = FileOrErr->get();
157+
(*CFS->OS).write(data, sizeof(data));
158+
},
159+
"")
160+
<< "destruction without commit did not cause error";
161+
162+
ASSERT_NO_ERROR(sys::fs::remove_directories(CacheDir.str()));
163+
}

0 commit comments

Comments
 (0)