Browse Source

Threading fixes & cleanup.

cl-refactor
Gav Wood 10 years ago
parent
commit
fda1fe5d37
  1. 78
      libp2p/NodeTable.cpp
  2. 4
      libp2p/NodeTable.h

78
libp2p/NodeTable.cpp

@ -127,20 +127,19 @@ void NodeTable::discover()
list<NodeId> NodeTable::nodes() const
{
list<NodeId> nodes;
Guard l(x_nodes);
for (auto& i: m_nodes)
nodes.push_back(i.second->id);
DEV_GUARDED(x_nodes)
for (auto& i: m_nodes)
nodes.push_back(i.second->id);
return move(nodes);
}
list<NodeEntry> NodeTable::snapshot() const
{
list<NodeEntry> ret;
Guard l(x_state);
for (auto s: m_state)
for (auto np: s.nodes)
if (auto n = np.lock())
if (!!n)
DEV_GUARDED(x_state)
for (auto const& s: m_state)
for (auto const& np: s.nodes)
if (auto n = np.lock())
ret.push_back(*n);
return move(ret);
}
@ -151,8 +150,7 @@ Node NodeTable::node(NodeId const& _id)
if (m_nodes.count(_id))
{
auto entry = m_nodes[_id];
Node n(_id, entry->endpoint, entry->required);
return move(n);
return Node(_id, entry->endpoint, entry->required);
}
return UnspecifiedNode;
}
@ -173,7 +171,7 @@ void NodeTable::discover(NodeId _node, unsigned _round, shared_ptr<set<shared_pt
clog(NodeTableEvent) << "Terminating discover after " << _round << " rounds.";
return;
}
else if(!_round && !_tried)
else if (!_round && !_tried)
// initialized _tried on first round
_tried.reset(new set<shared_ptr<NodeEntry>>());
@ -228,7 +226,7 @@ vector<shared_ptr<NodeEntry>> NodeTable::nearestNodeEntries(NodeId _target)
while (head != tail && head < s_bins && count < s_bucketSize)
{
Guard l(x_state);
for (auto n: m_state[head].nodes)
for (auto const& n: m_state[head].nodes)
if (auto p = n.lock())
{
if (count < s_bucketSize)
@ -238,7 +236,7 @@ vector<shared_ptr<NodeEntry>> NodeTable::nearestNodeEntries(NodeId _target)
}
if (count < s_bucketSize && tail)
for (auto n: m_state[tail].nodes)
for (auto const& n: m_state[tail].nodes)
if (auto p = n.lock())
{
if (count < s_bucketSize)
@ -255,7 +253,7 @@ vector<shared_ptr<NodeEntry>> NodeTable::nearestNodeEntries(NodeId _target)
while (head < s_bins && count < s_bucketSize)
{
Guard l(x_state);
for (auto n: m_state[head].nodes)
for (auto const& n: m_state[head].nodes)
if (auto p = n.lock())
{
if (count < s_bucketSize)
@ -269,7 +267,7 @@ vector<shared_ptr<NodeEntry>> NodeTable::nearestNodeEntries(NodeId _target)
while (tail > 0 && count < s_bucketSize)
{
Guard l(x_state);
for (auto n: m_state[tail].nodes)
for (auto const& n: m_state[tail].nodes)
if (auto p = n.lock())
{
if (count < s_bucketSize)
@ -282,7 +280,7 @@ vector<shared_ptr<NodeEntry>> NodeTable::nearestNodeEntries(NodeId _target)
vector<shared_ptr<NodeEntry>> ret;
for (auto& nodes: found)
for (auto n: nodes.second)
for (auto const& n: nodes.second)
if (ret.size() < s_bucketSize && !!n->endpoint && n->endpoint.isAllowed())
ret.push_back(n);
return move(ret);
@ -306,12 +304,15 @@ void NodeTable::evict(shared_ptr<NodeEntry> _leastSeen, shared_ptr<NodeEntry> _n
if (!m_socketPointer->isOpen())
return;
unsigned ec;
DEV_GUARDED(x_evictions)
{
Guard l(x_evictions);
m_evictions.push_back(EvictionTimeout(make_pair(_leastSeen->id,chrono::steady_clock::now()), _new->id));
if (m_evictions.size() == 1)
doCheckEvictions(boost::system::error_code());
ec = m_evictions.size();
}
if (ec == 1)
doCheckEvictions(boost::system::error_code());
ping(_leastSeen.get());
}
@ -428,24 +429,27 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes
Pong in = Pong::fromBytesConstRef(_from, rlpBytes);
// whenever a pong is received, check if it's in m_evictions
Guard le(x_evictions);
bool evictionEntry = false;
for (auto it = m_evictions.begin(); it != m_evictions.end(); it++)
if (it->first.first == nodeid && it->first.second > std::chrono::steady_clock::now())
{
evictionEntry = true;
if (auto n = nodeEntry(it->second))
dropNode(n);
if (auto n = nodeEntry(it->first.first))
n->pending = false;
it = m_evictions.erase(it);
}
// if not, check if it's known/pending or a pubk discovery ping
if (!evictionEntry)
bool found = false;
EvictionTimeout evictionEntry;
DEV_GUARDED(x_evictions)
for (auto it = m_evictions.begin(); it != m_evictions.end();)
if (it->first.first == nodeid && it->first.second > std::chrono::steady_clock::now())
{
found = true;
evictionEntry = *it;
m_evictions.erase(it);
break;
}
if (found)
{
if (auto n = nodeEntry(evictionEntry.second))
dropNode(n);
if (auto n = nodeEntry(evictionEntry.first.first))
n->pending = false;
}
else
{
// if not, check if it's known/pending or a pubk discovery ping
if (auto n = nodeEntry(nodeid))
n->pending = false;
else
@ -584,7 +588,7 @@ void NodeTable::doCheckEvictions(boost::system::error_code const& _ec)
if (chrono::steady_clock::now() - e.first.second > c_reqTimeout)
if (m_nodes.count(e.second))
drop.push_back(m_nodes[e.second]);
evictionsRemain = m_evictions.size() - drop.size() > 0;
evictionsRemain = (m_evictions.size() - drop.size() > 0);
}
drop.unique();

4
libp2p/NodeTable.h

@ -45,10 +45,12 @@ struct NodeEntry: public Node
bool pending = true; ///< Node will be ignored until Pong is received
};
enum NodeTableEventType {
enum NodeTableEventType
{
NodeEntryAdded,
NodeEntryDropped
};
class NodeTable;
class NodeTableEventHandler
{

Loading…
Cancel
Save