mirror of
https://github.com/dashpay/dash.git
synced 2024-12-26 12:32:48 +01:00
[wallet] Fix leak in CDB constructor
Now using a std::unique_ptr, the Db instance is correctly released when CDB initialization fails. The internal CDB state and mapFileUseCount are only mutated when the CDB initialization succeeds.
This commit is contained in:
parent
326a5652e0
commit
7104de8b1f
@ -379,45 +379,43 @@ CDB::CDB(CWalletDBWrapper& dbw, const char* pszMode, bool fFlushOnCloseIn) : pdb
|
|||||||
if (!env->Open(GetDataDir()))
|
if (!env->Open(GetDataDir()))
|
||||||
throw std::runtime_error("CDB: Failed to open database environment.");
|
throw std::runtime_error("CDB: Failed to open database environment.");
|
||||||
|
|
||||||
strFile = strFilename;
|
pdb = env->mapDb[strFilename];
|
||||||
++env->mapFileUseCount[strFile];
|
|
||||||
pdb = env->mapDb[strFile];
|
|
||||||
if (pdb == nullptr) {
|
if (pdb == nullptr) {
|
||||||
int ret;
|
int ret;
|
||||||
pdb = new Db(env->dbenv, 0);
|
std::unique_ptr<Db> pdb_temp(new Db(env->dbenv, 0));
|
||||||
|
|
||||||
bool fMockDb = env->IsMock();
|
bool fMockDb = env->IsMock();
|
||||||
if (fMockDb) {
|
if (fMockDb) {
|
||||||
DbMpoolFile* mpf = pdb->get_mpf();
|
DbMpoolFile* mpf = pdb_temp->get_mpf();
|
||||||
ret = mpf->set_flags(DB_MPOOL_NOFILE, 1);
|
ret = mpf->set_flags(DB_MPOOL_NOFILE, 1);
|
||||||
if (ret != 0)
|
if (ret != 0) {
|
||||||
throw std::runtime_error(strprintf("CDB: Failed to configure for no temp file backing for database %s", strFile));
|
throw std::runtime_error(strprintf("CDB: Failed to configure for no temp file backing for database %s", strFilename));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = pdb->open(nullptr, // Txn pointer
|
ret = pdb_temp->open(nullptr, // Txn pointer
|
||||||
fMockDb ? nullptr : strFile.c_str(), // Filename
|
fMockDb ? nullptr : strFilename.c_str(), // Filename
|
||||||
fMockDb ? strFile.c_str() : "main", // Logical db name
|
fMockDb ? strFilename.c_str() : "main", // Logical db name
|
||||||
DB_BTREE, // Database type
|
DB_BTREE, // Database type
|
||||||
nFlags, // Flags
|
nFlags, // Flags
|
||||||
0);
|
0);
|
||||||
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
delete pdb;
|
|
||||||
pdb = nullptr;
|
|
||||||
--env->mapFileUseCount[strFile];
|
|
||||||
strFile = "";
|
|
||||||
throw std::runtime_error(strprintf("CDB: Error %d, can't open database %s", ret, strFilename));
|
throw std::runtime_error(strprintf("CDB: Error %d, can't open database %s", ret, strFilename));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pdb = pdb_temp.release();
|
||||||
|
env->mapDb[strFilename] = pdb;
|
||||||
|
|
||||||
if (fCreate && !Exists(std::string("version"))) {
|
if (fCreate && !Exists(std::string("version"))) {
|
||||||
bool fTmp = fReadOnly;
|
bool fTmp = fReadOnly;
|
||||||
fReadOnly = false;
|
fReadOnly = false;
|
||||||
WriteVersion(CLIENT_VERSION);
|
WriteVersion(CLIENT_VERSION);
|
||||||
fReadOnly = fTmp;
|
fReadOnly = fTmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
env->mapDb[strFile] = pdb;
|
|
||||||
}
|
}
|
||||||
|
++env->mapFileUseCount[strFilename];
|
||||||
|
strFile = strFilename;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user