diff --git a/src/wallet/bdb.h b/src/wallet/bdb.h --- a/src/wallet/bdb.h +++ b/src/wallet/bdb.h @@ -116,12 +116,7 @@ assert(inserted.second); } - ~BerkeleyDatabase() { - if (env) { - size_t erased = env->m_databases.erase(strFile); - assert(erased == 1); - } - } + ~BerkeleyDatabase(); /** * Rewrite the entire database on disk, with the exception of key pszSkip if @@ -135,11 +130,17 @@ bool Backup(const std::string &strDest) const; /** - * Make sure all changes are flushed to disk. + * Make sure all changes are flushed to database file. */ - void Flush(bool shutdown); + void Flush(); - /* + /** + * Flush to the database file and close the database. + * Also close the environment if no other databases are open in it. + */ + void Close(); + + /** * flush the wallet passively (TRY_LOCK) * ideal to be called periodically */ diff --git a/src/wallet/bdb.cpp b/src/wallet/bdb.cpp --- a/src/wallet/bdb.cpp +++ b/src/wallet/bdb.cpp @@ -334,6 +334,15 @@ dbenv->lsn_reset(strFile.c_str(), 0); } +BerkeleyDatabase::~BerkeleyDatabase() { + if (env) { + LOCK(cs_db); + size_t erased = env->m_databases.erase(strFile); + assert(erased == 1); + env->m_fileids.erase(strFile); + } +} + BerkeleyBatch::BerkeleyBatch(BerkeleyDatabase &database, const char *pszMode, bool fFlushOnCloseIn) : pdb(nullptr), activeTxn(nullptr), m_cursor(nullptr) { @@ -757,22 +766,15 @@ } } -void BerkeleyDatabase::Flush(bool shutdown) { +void BerkeleyDatabase::Flush() { if (!IsDummy()) { - env->Flush(shutdown); - if (shutdown) { - LOCK(cs_db); - g_dbenvs.erase(env->Directory().string()); - env = nullptr; - } else { - // TODO: To avoid g_dbenvs.erase erasing the environment prematurely - // after the first database shutdown when multiple databases are - // open in the same environment, should replace raw database `env` - // pointers with shared or weak pointers, or else separate the - // database and environment shutdowns so environments can be shut - // down after databases. - env->m_fileids.erase(strFile); - } + env->Flush(false); + } +} + +void BerkeleyDatabase::Close() { + if (!IsDummy()) { + env->Flush(true); } } diff --git a/src/wallet/load.cpp b/src/wallet/load.cpp --- a/src/wallet/load.cpp +++ b/src/wallet/load.cpp @@ -124,13 +124,13 @@ void FlushWallets() { for (const std::shared_ptr &pwallet : GetWallets()) { - pwallet->Flush(false); + pwallet->Flush(); } } void StopWallets() { for (const std::shared_ptr &pwallet : GetWallets()) { - pwallet->Flush(true); + pwallet->Close(); } } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1316,7 +1316,10 @@ EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); //! Flush wallet (bitdb flush) - void Flush(bool shutdown = false); + void Flush(); + + //! Close wallet database + void Close(); /** Wallet is about to be unloaded */ boost::signals2::signal NotifyUnload; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -528,8 +528,12 @@ return (iter != mapTxSpends.end() && iter->first.GetTxId() == txid); } -void CWallet::Flush(bool shutdown) { - database->Flush(shutdown); +void CWallet::Flush() { + database->Flush(); +} + +void CWallet::Close() { + database->Close(); } void CWallet::SyncMetaData( diff --git a/src/wallet/wallettool.cpp b/src/wallet/wallettool.cpp --- a/src/wallet/wallettool.cpp +++ b/src/wallet/wallettool.cpp @@ -19,7 +19,7 @@ // deleter here. static void WalletToolReleaseWallet(CWallet *wallet) { wallet->WalletLogPrintf("Releasing wallet\n"); - wallet->Flush(true); + wallet->Close(); delete wallet; } @@ -132,7 +132,7 @@ std::shared_ptr wallet_instance = CreateWallet(name, path); if (wallet_instance) { WalletShowInfo(wallet_instance.get()); - wallet_instance->Flush(true); + wallet_instance->Close(); } } else if (command == "info" || command == "salvage") { if (!fs::exists(path)) { @@ -146,7 +146,7 @@ return false; } WalletShowInfo(wallet_instance.get()); - wallet_instance->Flush(true); + wallet_instance->Close(); } else if (command == "salvage") { bilingual_str error; std::vector warnings;