Fix SstFileWriter destructor

Summary:
If user did not call SstFileWriter::Finish() or called Finish() but it failed.
We need to abandon the builder, to avoid destructing it while it's open
Closes https://github.com/facebook/rocksdb/pull/1502

Differential Revision: D4171660

Pulled By: IslamAbdelRahman

fbshipit-source-id: ab6f434
This commit is contained in:
Islam AbdelRahman 2016-11-12 20:03:39 -08:00
parent 749cc74632
commit 35b5a76faf
2 changed files with 28 additions and 1 deletions

View File

@ -1761,6 +1761,25 @@ TEST_F(ExternalSSTFileTest, CompactionDeadlock) {
bg_block_put.join();
}
TEST_F(ExternalSSTFileTest, DirtyExit) {
Options options = CurrentOptions();
DestroyAndReopen(options);
std::string file_path = sst_files_dir_ + "/dirty_exit";
std::unique_ptr<SstFileWriter> sst_file_writer;
// Destruct SstFileWriter without calling Finish()
sst_file_writer.reset(
new SstFileWriter(EnvOptions(), options, options.comparator));
ASSERT_OK(sst_file_writer->Open(file_path));
sst_file_writer.reset();
// Destruct SstFileWriter with a failing Finish
sst_file_writer.reset(
new SstFileWriter(EnvOptions(), options, options.comparator));
ASSERT_OK(sst_file_writer->Open(file_path));
ASSERT_NOK(sst_file_writer->Finish());
}
#endif // ROCKSDB_LITE
} // namespace rocksdb

View File

@ -43,7 +43,15 @@ SstFileWriter::SstFileWriter(const EnvOptions& env_options,
const Comparator* user_comparator)
: rep_(new Rep(env_options, options, user_comparator)) {}
SstFileWriter::~SstFileWriter() { delete rep_; }
SstFileWriter::~SstFileWriter() {
if (rep_->builder) {
// User did not call Finish() or Finish() failed, we need to
// abandon the builder.
rep_->builder->Abandon();
}
delete rep_;
}
Status SstFileWriter::Open(const std::string& file_path) {
Rep* r = rep_;