Skip to content

Commit

Permalink
Merge pull request #439 from AntelopeIO/raf_nothrow_dtor
Browse files Browse the repository at this point in the history
guard against throwing in `random_access_file`'s `write_datastream` dtor
  • Loading branch information
spoonincode authored Aug 8, 2024
2 parents 7b286d8 + df51a09 commit c95db46
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 4 deletions.
24 changes: 20 additions & 4 deletions libraries/libfc/include/fc/io/random_access_file.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ read_ds() and write_ds() may be called from multiple threads simultaneously. The
fc's pack/unpack. Multiple read_datastream and write_datastream created from the same random_access_file can be used simultaneously from different
threads, but an individual read/write_datastream must only be used by a single thread at a time. unpack_from() and pack_to() are just
simple helper functions based on these read/write_datastreams. Be aware that read/write_datastreams are buffered. Write buffers are flushed
as needed, both upon destruction of the datastream and also when an internal buffer becomes full.
on an internal threshold, upon a call to flush(), and upon destruction of the datastream. If a buffered write fails during destruction an
exception is NOT thrown. So if acting upon write failure is important call flush() prior to destruction; flush() does throw on failure.
seekable_device() may be called from multiple threads simultaneously. This returns a Boost Iostreams SeekableDevice. Similar to datastreams,
multiple devices created from the same random_access_file can be used simultaneously from different threads, but an individual
Expand Down Expand Up @@ -320,7 +321,13 @@ class random_access_file {
}

void do_write() {
ctx->write_to(buffer.cdata(), next_pos);
try {
ctx->write_to(buffer.cdata(), next_pos);
} catch(...) {
//prevent another write attempt during dtor
buffer.clear();
throw;
}
if(next_pos != impl::append_t)
next_pos += buffer.size();
buffer.clear();
Expand All @@ -342,12 +349,19 @@ class random_access_file {
return true;
}

void flush() {
do_write();
}

inline bool put(char c) {
return write(&c, sizeof(char));
}

~write_datastream() {
if(ctx)
do_write();
try {
if(ctx)
do_write();
} FC_LOG_AND_DROP(("write failure ignored"));
}

private:
Expand Down Expand Up @@ -419,12 +433,14 @@ class random_access_file {
void pack_to(const T& v, const ssize_t offset) {
write_datastream ds(ctx, offset);
fc::raw::pack(ds, v);
ds.flush();
}

template<typename T>
void pack_to_end(const T& v) {
write_datastream ds(ctx, impl::append_t);
fc::raw::pack(ds, v);
ds.flush();
}

read_datastream read_ds(const ssize_t offset) {
Expand Down
2 changes: 2 additions & 0 deletions libraries/state_history/include/eosio/state_history/log.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,8 @@ class state_history_log {
const uint32_t num_blocks_in_log = _end_block - _begin_block;
fc::raw::pack(appender, num_blocks_in_log);
}

appender.flush();
}

std::optional<chain::block_id_type> get_block_id(uint32_t block_num) {
Expand Down

0 comments on commit c95db46

Please sign in to comment.