From 7b8b8307161e6c189c1bdc7a90aae72c665e777a Mon Sep 17 00:00:00 2001 From: Matt Witherspoon <32485495+spoonincode@users.noreply.github.com> Date: Tue, 16 Jan 2024 11:36:37 -0500 Subject: [PATCH] reset db dirty bit when ctor fails to complete --- src/pinnable_mapped_file.cpp | 32 ++++++++++++++++---------------- test/test.cpp | 17 +++++++++++++++++ 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/src/pinnable_mapped_file.cpp b/src/pinnable_mapped_file.cpp index 8d2e424..ed367ea 100644 --- a/src/pinnable_mapped_file.cpp +++ b/src/pinnable_mapped_file.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -163,6 +164,12 @@ pinnable_mapped_file::pinnable_mapped_file(const std::filesystem::path& dir, boo set_mapped_file_db_dirty(true); } + auto reset_dirty_on_ctor_fail = scope_fail([&]() { + if(_writable) + set_mapped_file_db_dirty(false); + std::erase(_instance_tracker, this); + }); + if(mode == mapped || mode == mapped_private) { if (_writable && !_sharable) { // First make sure the db file is not on a ram-based tempfs, as it would be an @@ -198,26 +205,19 @@ pinnable_mapped_file::pinnable_mapped_file(const std::filesystem::path& dir, boo BOOST_THROW_EXCEPTION(std::system_error(make_error_code(db_error_code::aborted))); }); - try { - setup_non_file_mapping(); - _file_mapped_region = bip::mapped_region(); - load_database_file(sig_ios); + setup_non_file_mapping(); + _file_mapped_region = bip::mapped_region(); + load_database_file(sig_ios); #ifndef _WIN32 - if(mode == locked) { - if(mlock(_non_file_mapped_mapping, _non_file_mapped_mapping_size)) { - std::string what_str("Failed to mlock database \"" + _database_name + "\""); - BOOST_THROW_EXCEPTION(std::system_error(make_error_code(db_error_code::no_mlock), what_str)); - } - std::cerr << "CHAINBASE: Database \"" << _database_name << "\" has been successfully locked in memory" << '\n'; + if(mode == locked) { + if(mlock(_non_file_mapped_mapping, _non_file_mapped_mapping_size)) { + std::string what_str("Failed to mlock database \"" + _database_name + "\""); + BOOST_THROW_EXCEPTION(std::system_error(make_error_code(db_error_code::no_mlock), what_str)); } -#endif - } - catch(...) { - if(_writable) - set_mapped_file_db_dirty(false); - throw; + std::cerr << "CHAINBASE: Database \"" << _database_name << "\" has been successfully locked in memory" << '\n'; } +#endif _segment_manager = reinterpret_cast((char*)_non_file_mapped_mapping+header_size); } diff --git a/test/test.cpp b/test/test.cpp index e3083db..f7f0885 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -127,4 +127,21 @@ BOOST_AUTO_TEST_CASE( open_and_create ) { BOOST_REQUIRE_EQUAL( new_book.b, copy_new_book.b ); } +BOOST_AUTO_TEST_CASE( mapped_big_boy ) { + temp_directory temp_dir; + const auto& temp = temp_dir.path(); + + BOOST_REQUIRE_THROW(chainbase::database(temp, database::read_write, 1024ull*1024*1024*1024*4, false, pinnable_mapped_file::map_mode::mapped_private), boost::interprocess::interprocess_exception); + chainbase::database(temp, database::read_write, 0, false); +} + +BOOST_AUTO_TEST_CASE( mapped_big_boy_extra ) { + temp_directory temp_dir; + const auto& temp = temp_dir.path(); + + chainbase::database(temp, database::read_write, 1024ull*1024*1024*1024*4, false); + BOOST_REQUIRE_THROW(chainbase::database(temp, database::read_write, 0, false, pinnable_mapped_file::map_mode::mapped_private), boost::interprocess::interprocess_exception); + chainbase::database(temp, database::read_write, 0, false); +} + // BOOST_AUTO_TEST_SUITE_END()