aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/db.h
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2019-01-31 18:01:30 +0100
committerWladimir J. van der Laan <laanwj@gmail.com>2019-01-31 18:05:24 +0100
commitefb6ddef9cb341428cbedf4373d1bdd19685a827 (patch)
tree15b9fecf5e60947c1a59a9765daa804ec82677dc /src/wallet/db.h
parent252fd15addf1cd061c3b6258ad916df7deeecf83 (diff)
parent14bc2a17dd03ccd89f65a302328763ff22c710c2 (diff)
downloadbitcoin-efb6ddef9cb341428cbedf4373d1bdd19685a827.tar.xz
Merge #11911: Free BerkeleyEnvironment instances when not in use
14bc2a17dd03ccd89f65a302328763ff22c710c2 Trivial: add doxygen-compatible comments relating to BerkeleyEnvironment (Pierre Rochard) 88b1d956fe3e38f2d2dd805feee9dadb0be9e8a9 Tests: add unit tests for GetWalletEnv (Pierre Rochard) f1f4bb7345b90853ec5037478173601035593d26 Free BerkeleyEnvironment instances when not in use (Russell Yanofsky) Pull request description: Instead of adding BerkeleyEnvironment objects permanently to the g_dbenvs map, use reference counted shared pointers and remove map entries when the last BerkeleyEnvironment reference goes out of scope. This change was requested by @TheBlueMatt and makes code that sets up mock databases cleaner. The mock database environment will now go out of scope and be reset on destruction so there is no need to call BerkeleyEnvironment::Reset() during wallet construction to clear out prior state. This change does affect bitcoin behavior slightly. On startup, instead of same wallet environments staying open throughout VerifyWallets() and OpenWallets() calls, VerifyWallets() will open and close an environment once for each wallet, and OpenWallets() will create its own environment(s) later. Tree-SHA512: 219d77a9e2268298435b86088f998795e059fdab1d2050ba284a9ab8d8a44961c9b5cf96e94ee521688108d23c6db680e3e3a999b8cb2ac2a8590f691d50668b
Diffstat (limited to 'src/wallet/db.h')
-rw-r--r--src/wallet/db.h34
1 files changed, 19 insertions, 15 deletions
diff --git a/src/wallet/db.h b/src/wallet/db.h
index 9dc373c89b..9df965305a 100644
--- a/src/wallet/db.h
+++ b/src/wallet/db.h
@@ -50,10 +50,10 @@ public:
std::condition_variable_any m_db_in_use;
BerkeleyEnvironment(const fs::path& env_directory);
+ BerkeleyEnvironment();
~BerkeleyEnvironment();
void Reset();
- void MakeMock();
bool IsMock() const { return fMockDb; }
bool IsInitialized() const { return fDbEnvInit; }
bool IsDatabaseLoaded(const std::string& db_filename) const { return m_databases.find(db_filename) != m_databases.end(); }
@@ -102,7 +102,7 @@ public:
bool IsWalletLoaded(const fs::path& wallet_path);
/** Get BerkeleyEnvironment and database filename given a wallet path. */
-BerkeleyEnvironment* GetWalletEnv(const fs::path& wallet_path, std::string& database_filename);
+std::shared_ptr<BerkeleyEnvironment> GetWalletEnv(const fs::path& wallet_path, std::string& database_filename);
/** An instance of this class represents one database.
* For BerkeleyDB this is just a (env, strFile) tuple.
@@ -117,17 +117,11 @@ public:
}
/** Create DB handle to real database */
- BerkeleyDatabase(const fs::path& wallet_path, bool mock = false) :
- nUpdateCounter(0), nLastSeen(0), nLastFlushed(0), nLastWalletUpdate(0)
+ BerkeleyDatabase(std::shared_ptr<BerkeleyEnvironment> env, std::string filename) :
+ nUpdateCounter(0), nLastSeen(0), nLastFlushed(0), nLastWalletUpdate(0), env(std::move(env)), strFile(std::move(filename))
{
- env = GetWalletEnv(wallet_path, strFile);
- auto inserted = env->m_databases.emplace(strFile, std::ref(*this));
+ auto inserted = this->env->m_databases.emplace(strFile, std::ref(*this));
assert(inserted.second);
- if (mock) {
- env->Close();
- env->Reset();
- env->MakeMock();
- }
}
~BerkeleyDatabase() {
@@ -140,7 +134,8 @@ public:
/** Return object for accessing database at specified path. */
static std::unique_ptr<BerkeleyDatabase> Create(const fs::path& path)
{
- return MakeUnique<BerkeleyDatabase>(path);
+ std::string filename;
+ return MakeUnique<BerkeleyDatabase>(GetWalletEnv(path, filename), std::move(filename));
}
/** Return object for accessing dummy database with no read/write capabilities. */
@@ -152,7 +147,7 @@ public:
/** Return object for accessing temporary in-memory database. */
static std::unique_ptr<BerkeleyDatabase> CreateMock()
{
- return MakeUnique<BerkeleyDatabase>("", true /* mock */);
+ return MakeUnique<BerkeleyDatabase>(std::make_shared<BerkeleyEnvironment>(), "");
}
/** Rewrite the entire database on disk, with the exception of key pszSkip if non-zero
@@ -176,12 +171,21 @@ public:
unsigned int nLastFlushed;
int64_t nLastWalletUpdate;
+ /**
+ * Pointer to shared database environment.
+ *
+ * Normally there is only one BerkeleyDatabase object per
+ * BerkeleyEnvivonment, but in the special, backwards compatible case where
+ * multiple wallet BDB data files are loaded from the same directory, this
+ * will point to a shared instance that gets freed when the last data file
+ * is closed.
+ */
+ std::shared_ptr<BerkeleyEnvironment> env;
+
/** Database pointer. This is initialized lazily and reset during flushes, so it can be null. */
std::unique_ptr<Db> m_db;
private:
- /** BerkeleyDB specific */
- BerkeleyEnvironment *env;
std::string strFile;
/** Return whether this database handle is a dummy for testing.