diff --git a/src/wallet/bdb.h b/src/wallet/bdb.h --- a/src/wallet/bdb.h +++ b/src/wallet/bdb.h @@ -124,6 +124,15 @@ */ bool Rewrite(const char *pszSkip = nullptr); + /** Indicate the a new database user has began using the database. */ + void AddRef(); + + /** + * Indicate that database user has stopped using the database and that it + * could be flushed or closed. + */ + void RemoveRef(); + /** * Back up the entire database to a file. */ @@ -226,6 +235,7 @@ bool fReadOnly; bool fFlushOnClose; BerkeleyEnvironment *env; + BerkeleyDatabase &m_database; public: explicit BerkeleyBatch(BerkeleyDatabase &database, diff --git a/src/wallet/bdb.cpp b/src/wallet/bdb.cpp --- a/src/wallet/bdb.cpp +++ b/src/wallet/bdb.cpp @@ -345,7 +345,8 @@ BerkeleyBatch::BerkeleyBatch(BerkeleyDatabase &database, const char *pszMode, bool fFlushOnCloseIn) - : pdb(nullptr), activeTxn(nullptr), m_cursor(nullptr) { + : pdb(nullptr), activeTxn(nullptr), m_cursor(nullptr), + m_database(database) { fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w')); fFlushOnClose = fFlushOnCloseIn; env = database.env.get(); @@ -430,7 +431,7 @@ fReadOnly = fTmp; } } - ++env->mapFileUseCount[strFilename]; + database.AddRef(); strFile = strFilename; } } @@ -476,11 +477,7 @@ Flush(); } - { - LOCK(cs_db); - --env->mapFileUseCount[strFile]; - } - env->m_db_in_use.notify_all(); + m_database.RemoveRef(); } void BerkeleyEnvironment::CloseDb(const std::string &strFile) { @@ -920,6 +917,19 @@ return ret == 0; } +void BerkeleyDatabase::AddRef() { + LOCK(cs_db); + ++env->mapFileUseCount[strFile]; +} + +void BerkeleyDatabase::RemoveRef() { + { + LOCK(cs_db); + --env->mapFileUseCount[strFile]; + } + env->m_db_in_use.notify_all(); +} + std::unique_ptr BerkeleyDatabase::MakeBatch(const char *mode, bool flush_on_close) { return std::make_unique(*this, mode, flush_on_close);