@@ -48,7 +48,7 @@ void CheckUniqueFileid(const BerkeleyEnvironment& env, const std::string& filena
48
48
}
49
49
50
50
CCriticalSection cs_db;
51
- std::map<std::string, BerkeleyEnvironment> g_dbenvs GUARDED_BY (cs_db); // !< Map from directory name to open db environment.
51
+ std::map<std::string, std::weak_ptr< BerkeleyEnvironment>> g_dbenvs GUARDED_BY (cs_db); // !< Map from directory name to db environment.
52
52
} // namespace
53
53
54
54
bool WalletDatabaseFileId::operator ==(const WalletDatabaseFileId& rhs) const
@@ -80,19 +80,22 @@ bool IsWalletLoaded(const fs::path& wallet_path)
80
80
LOCK (cs_db);
81
81
auto env = g_dbenvs.find (env_directory.string ());
82
82
if (env == g_dbenvs.end ()) return false ;
83
- return env->second .IsDatabaseLoaded (database_filename);
83
+ auto database = env->second .lock ();
84
+ return database && database->IsDatabaseLoaded (database_filename);
84
85
}
85
86
86
- BerkeleyEnvironment* GetWalletEnv (const fs::path& wallet_path, std::string& database_filename)
87
+ std::shared_ptr< BerkeleyEnvironment> GetWalletEnv (const fs::path& wallet_path, std::string& database_filename)
87
88
{
88
89
fs::path env_directory;
89
90
SplitWalletPath (wallet_path, env_directory, database_filename);
90
91
LOCK (cs_db);
91
- // Note: An unused temporary BerkeleyEnvironment object may be created inside the
92
- // emplace function if the key already exists. This is a little inefficient,
93
- // but not a big concern since the map will be changed in the future to hold
94
- // pointers instead of objects, anyway.
95
- return &g_dbenvs.emplace (std::piecewise_construct, std::forward_as_tuple (env_directory.string ()), std::forward_as_tuple (env_directory)).first ->second ;
92
+ auto inserted = g_dbenvs.emplace (env_directory.string (), std::weak_ptr<BerkeleyEnvironment>());
93
+ if (inserted.second ) {
94
+ auto env = std::make_shared<BerkeleyEnvironment>(env_directory.string ());
95
+ inserted.first ->second = env;
96
+ return env;
97
+ }
98
+ return inserted.first ->second .lock ();
96
99
}
97
100
98
101
//
@@ -137,6 +140,7 @@ BerkeleyEnvironment::BerkeleyEnvironment(const fs::path& dir_path) : strPath(dir
137
140
138
141
BerkeleyEnvironment::~BerkeleyEnvironment ()
139
142
{
143
+ g_dbenvs.erase (strPath);
140
144
Close ();
141
145
}
142
146
@@ -214,10 +218,9 @@ bool BerkeleyEnvironment::Open(bool retry)
214
218
return true ;
215
219
}
216
220
217
- void BerkeleyEnvironment::MakeMock ()
221
+ BerkeleyEnvironment::BerkeleyEnvironment ()
218
222
{
219
- if (fDbEnvInit )
220
- throw std::runtime_error (" BerkeleyEnvironment::MakeMock: Already initialized" );
223
+ Reset ();
221
224
222
225
boost::this_thread::interruption_point ();
223
226
@@ -266,7 +269,7 @@ BerkeleyEnvironment::VerifyResult BerkeleyEnvironment::Verify(const std::string&
266
269
bool BerkeleyBatch::Recover (const fs::path& file_path, void *callbackDataIn, bool (*recoverKVcallback)(void * callbackData, CDataStream ssKey, CDataStream ssValue), std::string& newFilename)
267
270
{
268
271
std::string filename;
269
- BerkeleyEnvironment* env = GetWalletEnv (file_path, filename);
272
+ std::shared_ptr< BerkeleyEnvironment> env = GetWalletEnv (file_path, filename);
270
273
271
274
// Recovery procedure:
272
275
// move wallet file to walletfilename.timestamp.bak
@@ -335,7 +338,7 @@ bool BerkeleyBatch::Recover(const fs::path& file_path, void *callbackDataIn, boo
335
338
bool BerkeleyBatch::VerifyEnvironment (const fs::path& file_path, std::string& errorStr)
336
339
{
337
340
std::string walletFile;
338
- BerkeleyEnvironment* env = GetWalletEnv (file_path, walletFile);
341
+ std::shared_ptr< BerkeleyEnvironment> env = GetWalletEnv (file_path, walletFile);
339
342
fs::path walletDir = env->Directory ();
340
343
341
344
LogPrintf (" Using BerkeleyDB version %s\n " , DbEnv::version (0 , 0 , 0 ));
@@ -359,7 +362,7 @@ bool BerkeleyBatch::VerifyEnvironment(const fs::path& file_path, std::string& er
359
362
bool BerkeleyBatch::VerifyDatabaseFile (const fs::path& file_path, std::string& warningStr, std::string& errorStr, BerkeleyEnvironment::recoverFunc_type recoverFunc)
360
363
{
361
364
std::string walletFile;
362
- BerkeleyEnvironment* env = GetWalletEnv (file_path, walletFile);
365
+ std::shared_ptr< BerkeleyEnvironment> env = GetWalletEnv (file_path, walletFile);
363
366
fs::path walletDir = env->Directory ();
364
367
365
368
if (fs::exists (walletDir / walletFile))
@@ -463,7 +466,7 @@ BerkeleyBatch::BerkeleyBatch(BerkeleyDatabase& database, const char* pszMode, bo
463
466
{
464
467
fReadOnly = (!strchr (pszMode, ' +' ) && !strchr (pszMode, ' w' ));
465
468
fFlushOnClose = fFlushOnCloseIn ;
466
- env = database.env ;
469
+ env = database.env . get () ;
467
470
if (database.IsDummy ()) {
468
471
return ;
469
472
}
@@ -520,7 +523,7 @@ BerkeleyBatch::BerkeleyBatch(BerkeleyDatabase& database, const char* pszMode, bo
520
523
// versions of BDB have an set_lk_exclusive method for this
521
524
// purpose, but the older version we use does not.)
522
525
for (const auto & env : g_dbenvs) {
523
- CheckUniqueFileid (env.second , strFilename, *pdb_temp, this ->env ->m_fileids [strFilename]);
526
+ CheckUniqueFileid (* env.second . lock (). get () , strFilename, *pdb_temp, this ->env ->m_fileids [strFilename]);
524
527
}
525
528
526
529
pdb = pdb_temp.release ();
@@ -621,7 +624,7 @@ bool BerkeleyBatch::Rewrite(BerkeleyDatabase& database, const char* pszSkip)
621
624
if (database.IsDummy ()) {
622
625
return true ;
623
626
}
624
- BerkeleyEnvironment *env = database.env ;
627
+ BerkeleyEnvironment *env = database.env . get () ;
625
628
const std::string& strFile = database.strFile ;
626
629
while (true ) {
627
630
{
@@ -752,7 +755,7 @@ bool BerkeleyBatch::PeriodicFlush(BerkeleyDatabase& database)
752
755
return true ;
753
756
}
754
757
bool ret = false ;
755
- BerkeleyEnvironment *env = database.env ;
758
+ BerkeleyEnvironment *env = database.env . get () ;
756
759
const std::string& strFile = database.strFile ;
757
760
TRY_LOCK (cs_db, lockDb);
758
761
if (lockDb)
0 commit comments