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" : ""); 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) if (m_state == SyncState::Idle && _s != SyncState::Idle)
_peer->m_requireTransactions = true; _peer->m_requireTransactions = true;

52
libethereum/BlockQueue.cpp

@ -37,7 +37,7 @@ const char* BlockQueueChannel::name() { return EthOrange "[]>"; }
const char* BlockQueueChannel::name() { return EthOrange "▣┅▶"; } const char* BlockQueueChannel::name() { return EthOrange "▣┅▶"; }
#endif #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_maxKnownSize = 128 * 1024 * 1024;
size_t const c_maxUnknownCount = 100000; size_t const c_maxUnknownCount = 100000;
size_t const c_maxUnknownSize = 512 * 1024 * 1024; // Block size can be ~50kb 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. // VERIFY: populates from the block and checks the block is internally coherent.
BlockInfo bi; BlockInfo bi;
try try
{ {
// TODO: quick verify // TODO: quick verify
@ -435,34 +436,35 @@ bool BlockQueue::unknownFull() const
void BlockQueue::drain(VerifiedBlocks& o_out, unsigned _max) void BlockQueue::drain(VerifiedBlocks& o_out, unsigned _max)
{ {
WriteGuard l(m_lock); bool wasFull = false;
DEV_INVARIANT_CHECK; DEV_WRITE_GUARDED(m_lock)
if (m_drainingSet.empty())
{ {
bool wasFull = knownFull(); DEV_INVARIANT_CHECK;
m_drainingDifficulty = 0; wasFull = knownFull();
DEV_GUARDED(m_verification) if (m_drainingSet.empty())
{
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>. m_drainingDifficulty = 0;
auto h = bs.verified.info.hash(); DEV_GUARDED(m_verification)
m_drainingSet.insert(h); {
m_drainingDifficulty += bs.verified.info.difficulty; o_out.resize(min<unsigned>(_max, m_verified.size()));
m_readySet.erase(h); for (unsigned i = 0; i < o_out.size(); ++i)
m_knownSize -= bs.verified.block.size(); swap(o_out[i], m_verified[i]);
m_knownCount--; 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 bool BlockQueue::invariants() const

Loading…
Cancel
Save