Skip to content

Commit

Permalink
#1545 state locking
Browse files Browse the repository at this point in the history
  • Loading branch information
kladkogex committed Jun 21, 2024
1 parent 71de8a5 commit d1aee99
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 12 deletions.
27 changes: 16 additions & 11 deletions libdevcore/LevelDB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,15 +172,18 @@ std::string LevelDB::lookup( Slice _key, const std::shared_ptr<LevelDBSnap>& _sn

auto readOptions = m_readOptions;

std::unique_ptr<std::shared_lock<std::shared_mutex>> snapshotUseLock;
if (_snap) {

// read from snap
readOptions.snapshot = _snap->getSnapHandle();
// create as shared lock on snap use mutex that will be unlocked on function exit
// this make sure snap is not concurrently closed while used
snapshotUseLock = _snap->lockToPreventConcurrentClose();
// this make sure snap is not concurrently closed while used in Get()
auto snapshotUseLock = _snap->lockToPreventConcurrentClose();
LDB_CHECK(!_snap->isClosed())
status = m_db->Get( readOptions, key, &value );
} else {
// read from live DB
status = m_db->Get( readOptions, key, &value );
}

status = m_db->Get( readOptions, key, &value );
}
if ( status.IsNotFound() )
return std::string();
Expand All @@ -203,15 +206,17 @@ bool LevelDB::exists( Slice _key, const std::shared_ptr<LevelDBSnap>& _snap ) c
SharedDBGuard lock( *this );
auto readOptions = m_readOptions;

std::unique_ptr<std::shared_lock<std::shared_mutex>> snapshotClosePreventionLock;
if (_snap) {
// read from snap
readOptions.snapshot = _snap->getSnapHandle();
// create as shared lock on snap close mutex that will be unlocked on function exit
// this make sure snap is not concurrently closed while used
snapshotClosePreventionLock = _snap->lockToPreventConcurrentClose();
// this make sure snap is not concurrently closed while used in Get()
auto snapshotUseLock = _snap->lockToPreventConcurrentClose();
status = m_db->Get( readOptions, key, &value );
} else {
// read from live DB
status = m_db->Get( readOptions, key, &value );
}

status = m_db->Get( readOptions, key, &value );
}
if ( status.IsNotFound() )
return false;
Expand Down
9 changes: 8 additions & 1 deletion libdevcore/LevelDBSnap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,18 @@
#include "LevelDB.h"

const leveldb::Snapshot* dev::db::LevelDBSnap::getSnapHandle() const {
LDB_CHECK(!m_isClosed)
return m_snap;
}

using std::string, std::runtime_error;

namespace dev::db {

bool LevelDBSnap::isClosed() const {
return m_isClosed;
}


LevelDBSnap::LevelDBSnap(
uint64_t _blockId, const leveldb::Snapshot* _snap, uint64_t _parentLevelDBIdentifier )
Expand Down Expand Up @@ -92,7 +97,9 @@ uint64_t LevelDBSnap::getCreationTimeMs() const {
return m_creationTimeMs;
}
std::unique_ptr<std::shared_lock<std::shared_mutex>> LevelDBSnap::lockToPreventConcurrentClose() {
return std::make_unique<std::shared_lock<std::shared_mutex>>( m_usageMutex );
// we are trying to use the snap, so it should not be closed
LDB_CHECK(!m_isClosed);
auto result = std::make_unique<std::shared_lock<std::shared_mutex>>( m_usageMutex );
}


Expand Down
1 change: 1 addition & 0 deletions libdevcore/LevelDBSnap.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class LevelDBSnap {
uint64_t getObjectId() const;

const leveldb::Snapshot* getSnapHandle() const;
bool isClosed() const;

private:

Expand Down

0 comments on commit d1aee99

Please sign in to comment.