Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
chainbase::pinnable_mapped_file Class Reference

#include <pinnable_mapped_file.hpp>

Public Types

enum  map_mode { mapped , heap , locked }
 
typedef bip::managed_mapped_file::segment_manager segment_manager
 

Public Member Functions

 pinnable_mapped_file (const bfs::path &dir, bool writable, uint64_t shared_file_size, bool allow_dirty, map_mode mode)
 
 pinnable_mapped_file (pinnable_mapped_file &&o)
 
pinnable_mapped_fileoperator= (pinnable_mapped_file &&)
 
 pinnable_mapped_file (const pinnable_mapped_file &)=delete
 
pinnable_mapped_fileoperator= (const pinnable_mapped_file &)=delete
 
 ~pinnable_mapped_file ()
 
segment_managerget_segment_manager () const
 

Detailed Description

Definition at line 40 of file pinnable_mapped_file.hpp.

Member Typedef Documentation

◆ segment_manager

bip::managed_mapped_file::segment_manager chainbase::pinnable_mapped_file::segment_manager

Definition at line 42 of file pinnable_mapped_file.hpp.

Member Enumeration Documentation

◆ map_mode

Constructor & Destructor Documentation

◆ pinnable_mapped_file() [1/3]

chainbase::pinnable_mapped_file::pinnable_mapped_file ( const bfs::path & dir,
bool writable,
uint64_t shared_file_size,
bool allow_dirty,
map_mode mode )

Definition at line 53 of file pinnable_mapped_file.cpp.

53 :
54 _data_file_path(bfs::absolute(dir/"shared_memory.bin")),
55 _database_name(dir.filename().string()),
56 _writable(writable)
57{
58 if(shared_file_size % _db_size_multiple_requirement) {
59 std::string what_str("Database must be mulitple of " + std::to_string(_db_size_multiple_requirement) + " bytes");
60 BOOST_THROW_EXCEPTION(std::system_error(make_error_code(db_error_code::bad_size), what_str));
61 }
62#ifdef _WIN32
63 if(mode != mapped)
64 BOOST_THROW_EXCEPTION(std::system_error(make_error_code(db_error_code::unsupported_win32_mode)));
65#endif
66 if(!_writable && !bfs::exists(_data_file_path)){
67 std::string what_str("database file not found at " + _data_file_path.string());
68 BOOST_THROW_EXCEPTION(std::system_error(make_error_code(db_error_code::not_found), what_str));
69 }
70
71 bfs::create_directories(dir);
72
73 if(bfs::exists(_data_file_path)) {
74 char header[header_size];
75 std::ifstream hs(_data_file_path.generic_string(), std::ifstream::binary);
76 hs.read(header, header_size);
77 if(hs.fail())
78 BOOST_THROW_EXCEPTION(std::system_error(make_error_code(db_error_code::bad_header)));
79
80 db_header* dbheader = reinterpret_cast<db_header*>(header);
81 if(dbheader->id != header_id) {
82 std::string what_str("\"" + _database_name + "\" database format not compatible with this version of chainbase.");
83 BOOST_THROW_EXCEPTION(std::system_error(make_error_code(db_error_code::incorrect_db_version), what_str));
84 }
85 if(!allow_dirty && dbheader->dirty) {
86 std::string what_str("\"" + _database_name + "\" database dirty flag set");
87 BOOST_THROW_EXCEPTION(std::system_error(make_error_code(db_error_code::dirty)));
88 }
89 if(dbheader->dbenviron != environment()) {
90 std::cerr << "CHAINBASE: \"" << _database_name << "\" database was created with a chainbase from a different environment" << std::endl;
91 std::cerr << "Current compiler environment:" << std::endl;
92 std::cerr << environment();
93 std::cerr << "DB created with compiler environment:" << std::endl;
94 std::cerr << dbheader->dbenviron;
95 BOOST_THROW_EXCEPTION(std::system_error(make_error_code(db_error_code::incompatible)));
96 }
97 }
98
99 segment_manager* file_mapped_segment_manager = nullptr;
100 if(!bfs::exists(_data_file_path)) {
101 std::ofstream ofs(_data_file_path.generic_string(), std::ofstream::trunc);
102 //win32 impl of bfs::resize_file() doesn't like the file being open
103 ofs.close();
104 bfs::resize_file(_data_file_path, shared_file_size);
105 _file_mapping = bip::file_mapping(_data_file_path.generic_string().c_str(), bip::read_write);
106 _file_mapped_region = bip::mapped_region(_file_mapping, bip::read_write);
107 file_mapped_segment_manager = new ((char*)_file_mapped_region.get_address()+header_size) segment_manager(shared_file_size-header_size);
108 new (_file_mapped_region.get_address()) db_header;
109 }
110 else if(_writable) {
111 auto existing_file_size = bfs::file_size(_data_file_path);
112 size_t grow = 0;
113 if(shared_file_size > existing_file_size) {
114 grow = shared_file_size - existing_file_size;
115 bfs::resize_file(_data_file_path, shared_file_size);
116 }
117 else if(shared_file_size < existing_file_size) {
118 std::cerr << "CHAINBASE: \"" << _database_name << "\" requested size of " << shared_file_size << " is less than "
119 "existing size of " << existing_file_size << ". This database will not be shrunk and will "
120 "remain at " << existing_file_size << std::endl;
121 }
122 _file_mapping = bip::file_mapping(_data_file_path.generic_string().c_str(), bip::read_write);
123 _file_mapped_region = bip::mapped_region(_file_mapping, bip::read_write);
124 file_mapped_segment_manager = reinterpret_cast<segment_manager*>((char*)_file_mapped_region.get_address()+header_size);
125 if(grow)
126 file_mapped_segment_manager->grow(grow);
127 }
128 else {
129 _file_mapping = bip::file_mapping(_data_file_path.generic_string().c_str(), bip::read_only);
130 _file_mapped_region = bip::mapped_region(_file_mapping, bip::read_only);
131 file_mapped_segment_manager = reinterpret_cast<segment_manager*>((char*)_file_mapped_region.get_address()+header_size);
132 }
133
134 if(_writable) {
135 //remove meta file created in earlier versions
136 boost::system::error_code ec;
137 bfs::remove(bfs::absolute(dir/"shared_memory.meta"), ec);
138
139 _mapped_file_lock = bip::file_lock(_data_file_path.generic_string().c_str());
140 if(!_mapped_file_lock.try_lock())
141 BOOST_THROW_EXCEPTION(std::system_error(make_error_code(db_error_code::no_access)));
142
143 set_mapped_file_db_dirty(true);
144 }
145
146 if(mode == mapped) {
147 _segment_manager = file_mapped_segment_manager;
148 }
149 else {
150 boost::asio::io_service sig_ios;
151 boost::asio::signal_set sig_set(sig_ios, SIGINT, SIGTERM);
152#ifdef SIGPIPE
153 sig_set.add(SIGPIPE);
154#endif
155 sig_set.async_wait([](const boost::system::error_code&, int) {
156 BOOST_THROW_EXCEPTION(std::system_error(make_error_code(db_error_code::aborted)));
157 });
158
159 try {
160 setup_non_file_mapping();
161 load_database_file(sig_ios);
162
163#ifndef _WIN32
164 if(mode == locked) {
165 if(mlock(_non_file_mapped_mapping, _non_file_mapped_mapping_size)) {
166 std::string what_str("Failed to mlock database \"" + _database_name + "\"");
167 BOOST_THROW_EXCEPTION(std::system_error(make_error_code(db_error_code::no_mlock), what_str));
168 }
169 std::cerr << "CHAINBASE: Database \"" << _database_name << "\" has been successfully locked in memory" << std::endl;
170 }
171#endif
172
173 _file_mapped_region = bip::mapped_region();
174 }
175 catch(...) {
176 if(_writable)
177 set_mapped_file_db_dirty(false);
178 throw;
179 }
180
181 _segment_manager = reinterpret_cast<segment_manager*>((char*)_non_file_mapped_mapping+header_size);
182 }
183}
bip::managed_mapped_file::segment_manager segment_manager
environment()
std::error_code make_error_code(db_error_code e) noexcept
constexpr size_t header_size
constexpr uint64_t header_id
Here is the call graph for this function:

◆ pinnable_mapped_file() [2/3]

chainbase::pinnable_mapped_file::pinnable_mapped_file ( pinnable_mapped_file && o)

Definition at line 284 of file pinnable_mapped_file.cpp.

284 :
285 _mapped_file_lock(std::move(o._mapped_file_lock)),
286 _data_file_path(std::move(o._data_file_path)),
287 _database_name(std::move(o._database_name)),
288 _file_mapped_region(std::move(o._file_mapped_region))
289{
290 _segment_manager = o._segment_manager;
291 _writable = o._writable;
292 _non_file_mapped_mapping = o._non_file_mapped_mapping;
293 o._non_file_mapped_mapping = nullptr;
294 o._writable = false; //prevent dtor from doing anything interesting
295}

◆ pinnable_mapped_file() [3/3]

chainbase::pinnable_mapped_file::pinnable_mapped_file ( const pinnable_mapped_file & )
delete

◆ ~pinnable_mapped_file()

chainbase::pinnable_mapped_file::~pinnable_mapped_file ( )

Definition at line 310 of file pinnable_mapped_file.cpp.

310 {
311 if(_writable) {
312 if(_non_file_mapped_mapping) { //in heap or locked mode
313 _file_mapped_region = bip::mapped_region(_file_mapping, bip::read_write);
314 save_database_file();
315#ifndef _WIN32
316 if(munmap(_non_file_mapped_mapping, _non_file_mapped_mapping_size))
317 std::cerr << "CHAINBASE: ERROR: unmapping failed: " << strerror(errno) << std::endl;
318#endif
319 }
320 else
321 if(_file_mapped_region.flush(0, 0, false) == false)
322 std::cerr << "CHAINBASE: ERROR: syncing buffers failed" << std::endl;
323 set_mapped_file_db_dirty(false);
324 }
325}

Member Function Documentation

◆ get_segment_manager()

segment_manager * chainbase::pinnable_mapped_file::get_segment_manager ( ) const
inline

Definition at line 57 of file pinnable_mapped_file.hpp.

57{ return _segment_manager;}
Here is the caller graph for this function:

◆ operator=() [1/2]

pinnable_mapped_file & chainbase::pinnable_mapped_file::operator= ( const pinnable_mapped_file & )
delete

◆ operator=() [2/2]

pinnable_mapped_file & chainbase::pinnable_mapped_file::operator= ( pinnable_mapped_file && o)

Definition at line 297 of file pinnable_mapped_file.cpp.

297 {
298 _mapped_file_lock = std::move(o._mapped_file_lock);
299 _data_file_path = std::move(o._data_file_path);
300 _database_name = std::move(o._database_name);
301 _file_mapped_region = std::move(o._file_mapped_region);
302 _non_file_mapped_mapping = o._non_file_mapped_mapping;
303 o._non_file_mapped_mapping = nullptr;
304 _segment_manager = o._segment_manager;
305 _writable = o._writable;
306 o._writable = false; //prevent dtor from doing anything interesting
307 return *this;
308}

The documentation for this class was generated from the following files: