Browse Source

fixed deadlock on resume

cl-refactor
arkpar 10 years ago
parent
commit
2fe2b202b8
  1. 1
      libethereum/BlockChainSync.cpp
  2. 52
      libethereum/BlockQueue.cpp

1
libethereum/BlockChainSync.cpp

@ -364,7 +364,6 @@ void PV60Sync::transition(EthereumPeer* _peer, SyncState _s, bool _force, bool _
{
clog(NetMessageSummary) << "Transition!" << EthereumHost::stateName(_s) << "from" << EthereumHost::stateName(m_state) << ", " << (isSyncing(_peer) ? "syncing" : "holding") << (needsSyncing(_peer) ? "& needed" : "");
//DEV_INVARIANT_CHECK;
if (m_state == SyncState::Idle && _s != SyncState::Idle)
_peer->m_requireTransactions = true;

52
libethereum/BlockQueue.cpp

@ -37,7 +37,7 @@ const char* BlockQueueChannel::name() { return EthOrange "[]>"; }
const char* BlockQueueChannel::name() { return EthOrange "▣┅▶"; }
#endif
size_t const c_maxKnownCount = 100000;
size_t const c_maxKnownCount = 10000;
size_t const c_maxKnownSize = 128 * 1024 * 1024;
size_t const c_maxUnknownCount = 100000;
size_t const c_maxUnknownSize = 512 * 1024 * 1024; // Block size can be ~50kb
@ -196,6 +196,7 @@ ImportResult BlockQueue::import(bytesConstRef _block, BlockChain const& _bc, boo
// VERIFY: populates from the block and checks the block is internally coherent.
BlockInfo bi;
try
{
// TODO: quick verify
@ -435,34 +436,35 @@ bool BlockQueue::unknownFull() const
void BlockQueue::drain(VerifiedBlocks& o_out, unsigned _max)
{
WriteGuard l(m_lock);
DEV_INVARIANT_CHECK;
if (m_drainingSet.empty())
bool wasFull = false;
DEV_WRITE_GUARDED(m_lock)
{
bool wasFull = knownFull();
m_drainingDifficulty = 0;
DEV_GUARDED(m_verification)
{
o_out.resize(min<unsigned>(_max, m_verified.size()));
for (unsigned i = 0; i < o_out.size(); ++i)
swap(o_out[i], m_verified[i]);
m_verified.erase(m_verified.begin(), advanced(m_verified.begin(), o_out.size()));
}
for (auto const& bs: o_out)
DEV_INVARIANT_CHECK;
wasFull = knownFull();
if (m_drainingSet.empty())
{
// TODO: @optimise use map<h256, bytes> rather than vector<bytes> & set<h256>.
auto h = bs.verified.info.hash();
m_drainingSet.insert(h);
m_drainingDifficulty += bs.verified.info.difficulty;
m_readySet.erase(h);
m_knownSize -= bs.verified.block.size();
m_knownCount--;
m_drainingDifficulty = 0;
DEV_GUARDED(m_verification)
{
o_out.resize(min<unsigned>(_max, m_verified.size()));
for (unsigned i = 0; i < o_out.size(); ++i)
swap(o_out[i], m_verified[i]);
m_verified.erase(m_verified.begin(), advanced(m_verified.begin(), o_out.size()));
}
for (auto const& bs: o_out)
{
// TODO: @optimise use map<h256, bytes> rather than vector<bytes> & set<h256>.
auto h = bs.verified.info.hash();
m_drainingSet.insert(h);
m_drainingDifficulty += bs.verified.info.difficulty;
m_readySet.erase(h);
m_knownSize -= bs.verified.block.size();
m_knownCount--;
}
}
if (wasFull && !knownFull())
m_onRoomAvailable();
}
if (wasFull && !knownFull())
m_onRoomAvailable();
}
bool BlockQueue::invariants() const

Loading…
Cancel
Save