Merge pull request #3940

f24cbc5 blockchain: fix deadlock with the difficulty cache (moneromooo-monero)
This commit is contained in:
luigi1111 2018-06-07 12:19:43 -05:00
commit 8a1f0d7d13
No known key found for this signature in database
GPG Key ID: F4ACA0183641E010

View File

@ -807,16 +807,18 @@ difficulty_type Blockchain::get_difficulty_for_next_block()
{ {
LOG_PRINT_L3("Blockchain::" << __func__); LOG_PRINT_L3("Blockchain::" << __func__);
CRITICAL_REGION_LOCAL(m_difficulty_lock);
// we can call this without the blockchain lock, it might just give us
// something a bit out of date, but that's fine since anything which
// requires the blockchain lock will have acquired it in the first place,
// and it will be unlocked only when called from the getinfo RPC
crypto::hash top_hash = get_tail_id(); crypto::hash top_hash = get_tail_id();
if (top_hash == m_difficulty_for_next_block_top_hash) {
return m_difficulty_for_next_block; CRITICAL_REGION_LOCAL(m_difficulty_lock);
// we can call this without the blockchain lock, it might just give us
// something a bit out of date, but that's fine since anything which
// requires the blockchain lock will have acquired it in the first place,
// and it will be unlocked only when called from the getinfo RPC
if (top_hash == m_difficulty_for_next_block_top_hash)
return m_difficulty_for_next_block;
}
CRITICAL_REGION_LOCAL1(m_blockchain_lock); CRITICAL_REGION_LOCAL(m_blockchain_lock);
std::vector<uint64_t> timestamps; std::vector<uint64_t> timestamps;
std::vector<difficulty_type> difficulties; std::vector<difficulty_type> difficulties;
auto height = m_db->height(); auto height = m_db->height();
@ -860,6 +862,8 @@ difficulty_type Blockchain::get_difficulty_for_next_block()
} }
size_t target = get_difficulty_target(); size_t target = get_difficulty_target();
difficulty_type diff = next_difficulty(timestamps, difficulties, target); difficulty_type diff = next_difficulty(timestamps, difficulties, target);
CRITICAL_REGION_LOCAL1(m_difficulty_lock);
m_difficulty_for_next_block_top_hash = top_hash; m_difficulty_for_next_block_top_hash = top_hash;
m_difficulty_for_next_block = diff; m_difficulty_for_next_block = diff;
return diff; return diff;