mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 03:52:49 +01:00
Replace generic CScopedDBTransaction with specialized CEvoDBScopedCommitter (#3292)
This has the wanted side effect of proper locking of "cs" inside CommitCurTransaction and RollbackCurTransaction, which was not easily possible to implement in the generic version. This fixes some rare crashes.
This commit is contained in:
parent
8fd486c6bc
commit
1d9adbe639
@ -724,49 +724,4 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Parent, typename CommitTarget>
|
||||
class CScopedDBTransaction {
|
||||
public:
|
||||
typedef CDBTransaction<Parent, CommitTarget> Transaction;
|
||||
|
||||
private:
|
||||
Transaction &dbTransaction;
|
||||
std::function<void ()> commitHandler;
|
||||
std::function<void ()> rollbackHandler;
|
||||
bool didCommitOrRollback{};
|
||||
|
||||
public:
|
||||
CScopedDBTransaction(Transaction &dbTx) : dbTransaction(dbTx) {}
|
||||
~CScopedDBTransaction() {
|
||||
if (!didCommitOrRollback)
|
||||
Rollback();
|
||||
}
|
||||
void Commit() {
|
||||
assert(!didCommitOrRollback);
|
||||
didCommitOrRollback = true;
|
||||
dbTransaction.Commit();
|
||||
if (commitHandler)
|
||||
commitHandler();
|
||||
}
|
||||
void Rollback() {
|
||||
assert(!didCommitOrRollback);
|
||||
didCommitOrRollback = true;
|
||||
dbTransaction.Clear();
|
||||
if (rollbackHandler)
|
||||
rollbackHandler();
|
||||
}
|
||||
|
||||
static std::unique_ptr<CScopedDBTransaction<Parent, CommitTarget>> Begin(Transaction &dbTx) {
|
||||
assert(dbTx.IsClean());
|
||||
return std::make_unique<CScopedDBTransaction<Parent, CommitTarget>>(dbTx);
|
||||
}
|
||||
|
||||
void SetCommitHandler(const std::function<void ()> &h) {
|
||||
commitHandler = h;
|
||||
}
|
||||
void SetRollbackHandler(const std::function<void ()> &h) {
|
||||
rollbackHandler = h;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // BITCOIN_DBWRAPPER_H
|
||||
|
@ -6,6 +6,31 @@
|
||||
|
||||
CEvoDB* evoDb;
|
||||
|
||||
CEvoDBScopedCommitter::CEvoDBScopedCommitter(CEvoDB &_evoDB) :
|
||||
evoDB(_evoDB)
|
||||
{
|
||||
}
|
||||
|
||||
CEvoDBScopedCommitter::~CEvoDBScopedCommitter()
|
||||
{
|
||||
if (!didCommitOrRollback)
|
||||
Rollback();
|
||||
}
|
||||
|
||||
void CEvoDBScopedCommitter::Commit()
|
||||
{
|
||||
assert(!didCommitOrRollback);
|
||||
didCommitOrRollback = true;
|
||||
evoDB.CommitCurTransaction();
|
||||
}
|
||||
|
||||
void CEvoDBScopedCommitter::Rollback()
|
||||
{
|
||||
assert(!didCommitOrRollback);
|
||||
didCommitOrRollback = true;
|
||||
evoDB.RollbackCurTransaction();
|
||||
}
|
||||
|
||||
CEvoDB::CEvoDB(size_t nCacheSize, bool fMemory, bool fWipe) :
|
||||
db(fMemory ? "" : (GetDataDir() / "evodb"), nCacheSize, fMemory, fWipe),
|
||||
rootBatch(db),
|
||||
@ -14,6 +39,18 @@ CEvoDB::CEvoDB(size_t nCacheSize, bool fMemory, bool fWipe) :
|
||||
{
|
||||
}
|
||||
|
||||
void CEvoDB::CommitCurTransaction()
|
||||
{
|
||||
LOCK(cs);
|
||||
curDBTransaction.Commit();
|
||||
}
|
||||
|
||||
void CEvoDB::RollbackCurTransaction()
|
||||
{
|
||||
LOCK(cs);
|
||||
curDBTransaction.Clear();
|
||||
}
|
||||
|
||||
bool CEvoDB::CommitRootTransaction()
|
||||
{
|
||||
assert(curDBTransaction.IsClean());
|
||||
|
@ -13,6 +13,22 @@
|
||||
// "b_b2" was used after compact diffs were introduced
|
||||
static const std::string EVODB_BEST_BLOCK = "b_b2";
|
||||
|
||||
class CEvoDB;
|
||||
|
||||
class CEvoDBScopedCommitter
|
||||
{
|
||||
private:
|
||||
CEvoDB& evoDB;
|
||||
bool didCommitOrRollback{false};
|
||||
|
||||
public:
|
||||
explicit CEvoDBScopedCommitter(CEvoDB& _evoDB);
|
||||
~CEvoDBScopedCommitter();
|
||||
|
||||
void Commit();
|
||||
void Rollback();
|
||||
};
|
||||
|
||||
class CEvoDB
|
||||
{
|
||||
private:
|
||||
@ -21,7 +37,6 @@ private:
|
||||
|
||||
typedef CDBTransaction<CDBWrapper, CDBBatch> RootTransaction;
|
||||
typedef CDBTransaction<RootTransaction, RootTransaction> CurTransaction;
|
||||
typedef CScopedDBTransaction<RootTransaction, RootTransaction> ScopedTransaction;
|
||||
|
||||
CDBBatch rootBatch;
|
||||
RootTransaction rootDBTransaction;
|
||||
@ -30,11 +45,10 @@ private:
|
||||
public:
|
||||
CEvoDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false);
|
||||
|
||||
std::unique_ptr<ScopedTransaction> BeginTransaction()
|
||||
std::unique_ptr<CEvoDBScopedCommitter> BeginTransaction()
|
||||
{
|
||||
LOCK(cs);
|
||||
auto t = ScopedTransaction::Begin(curDBTransaction);
|
||||
return t;
|
||||
return std::make_unique<CEvoDBScopedCommitter>(*this);
|
||||
}
|
||||
|
||||
CurTransaction& GetCurTransaction()
|
||||
@ -84,6 +98,12 @@ public:
|
||||
|
||||
bool VerifyBestBlock(const uint256& hash);
|
||||
void WriteBestBlock(const uint256& hash);
|
||||
|
||||
private:
|
||||
// only CEvoDBScopedCommitter is allowed to invoke these
|
||||
friend class CEvoDBScopedCommitter;
|
||||
void CommitCurTransaction();
|
||||
void RollbackCurTransaction();
|
||||
};
|
||||
|
||||
extern CEvoDB* evoDb;
|
||||
|
Loading…
Reference in New Issue
Block a user