sstable: close file_writer if an exception in thrown
The previous code was not exception safe and would eventually cause a file to be destroyed without being closed, causing an assert failure. Unfortunately it doesn't seem to be possible to test this without error injection, since using an invalid directory fails before this code is executed. Fixes #4948 Signed-off-by: Rafael Ávila de Espíndola <espindola@scylladb.com> Message-Id: <20190904002314.79591-1-espindola@scylladb.com>
This commit is contained in:
committed by
Avi Kivity
parent
bdfb73f67d
commit
000514e7cc
@@ -1056,9 +1056,26 @@ void sstable::write_simple(const T& component, const io_priority_class& pc) {
|
||||
options.buffer_size = sstable_buffer_size;
|
||||
options.io_priority_class = pc;
|
||||
auto w = file_writer(std::move(f), std::move(options));
|
||||
write(_version, w, component);
|
||||
w.flush();
|
||||
w.close();
|
||||
std::exception_ptr eptr;
|
||||
try {
|
||||
write(_version, w, component);
|
||||
w.flush();
|
||||
} catch (...) {
|
||||
eptr = std::current_exception();
|
||||
}
|
||||
try {
|
||||
w.close();
|
||||
} catch (...) {
|
||||
std::exception_ptr close_eptr = std::current_exception();
|
||||
sstlog.warn("failed to close file_writer: {}", close_eptr);
|
||||
// If write succeeded but close failed, we rethrow close's exception.
|
||||
if (!eptr) {
|
||||
eptr = close_eptr;
|
||||
}
|
||||
}
|
||||
if (eptr) {
|
||||
std::rethrow_exception(eptr);
|
||||
}
|
||||
}
|
||||
|
||||
template future<> sstable::read_simple<component_type::Filter>(sstables::filter& f, const io_priority_class& pc);
|
||||
|
||||
Reference in New Issue
Block a user