From 9e7c778cc8ebdfd5d3f773a7d3cb30ad154e7189 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Fri, 27 Jan 2017 16:16:06 -0800 Subject: Fix deadlock. --- node/Topology.cpp | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) (limited to 'node/Topology.cpp') diff --git a/node/Topology.cpp b/node/Topology.cpp index ece93ee6..5632c337 100644 --- a/node/Topology.cpp +++ b/node/Topology.cpp @@ -79,7 +79,7 @@ SharedPtr Topology::addPeer(const SharedPtr &peer) SharedPtr np; { - Mutex::Lock _l(_lock); + Mutex::Lock _l(_peers_m); SharedPtr &hp = _peers[peer->address()]; if (!hp) hp = peer; @@ -99,7 +99,7 @@ SharedPtr Topology::getPeer(const Address &zta) } { - Mutex::Lock _l(_lock); + Mutex::Lock _l(_peers_m); const SharedPtr *const ap = _peers.get(zta); if (ap) return *ap; @@ -110,7 +110,7 @@ SharedPtr Topology::getPeer(const Address &zta) if (id) { SharedPtr np(new Peer(RR,RR->identity,id)); { - Mutex::Lock _l(_lock); + Mutex::Lock _l(_peers_m); SharedPtr &ap = _peers[zta]; if (!ap) ap.swap(np); @@ -127,7 +127,7 @@ Identity Topology::getIdentity(const Address &zta) if (zta == RR->identity.address()) { return RR->identity; } else { - Mutex::Lock _l(_lock); + Mutex::Lock _l(_peers_m); const SharedPtr *const ap = _peers.get(zta); if (ap) return (*ap)->identity(); @@ -147,7 +147,8 @@ void Topology::saveIdentity(const Identity &id) SharedPtr Topology::getUpstreamPeer(const Address *avoid,unsigned int avoidCount,bool strictAvoid) { const uint64_t now = RR->node->now(); - Mutex::Lock _l(_lock); + Mutex::Lock _l1(_peers_m); + Mutex::Lock _l2(_upstreams_m); if (_amRoot) { /* If I am a root, pick another root that isn't mine and that @@ -208,13 +209,13 @@ SharedPtr Topology::getUpstreamPeer(const Address *avoid,unsigned int avoi bool Topology::isUpstream(const Identity &id) const { - Mutex::Lock _l(_lock); + Mutex::Lock _l(_upstreams_m); return (std::find(_upstreamAddresses.begin(),_upstreamAddresses.end(),id.address()) != _upstreamAddresses.end()); } ZT_PeerRole Topology::role(const Address &ztaddr) const { - Mutex::Lock _l(_lock); + Mutex::Lock _l(_upstreams_m); if (std::find(_upstreamAddresses.begin(),_upstreamAddresses.end(),ztaddr) != _upstreamAddresses.end()) { for(std::vector::const_iterator i(_planet.roots().begin());i!=_planet.roots().end();++i) { if (i->identity.address() == ztaddr) @@ -227,7 +228,7 @@ ZT_PeerRole Topology::role(const Address &ztaddr) const bool Topology::isProhibitedEndpoint(const Address &ztaddr,const InetAddress &ipaddr) const { - Mutex::Lock _l(_lock); + Mutex::Lock _l(_upstreams_m); // For roots the only permitted addresses are those defined. This adds just a little // bit of extra security against spoofing, replaying, etc. @@ -257,7 +258,8 @@ bool Topology::addWorld(const World &newWorld) if ((newWorld.type() != World::TYPE_PLANET)&&(newWorld.type() != World::TYPE_MOON)) return false; - Mutex::Lock _l(_lock); + Mutex::Lock _l1(_upstreams_m); + Mutex::Lock _l2(_peers_m); World *existing = (World *)0; switch(newWorld.type()) { @@ -313,7 +315,7 @@ void Topology::addMoon(const uint64_t id) { { const Address a(id >> 24); - Mutex::Lock _l(_lock); + Mutex::Lock _l(_upstreams_m); if (std::find(_contactingMoons.begin(),_contactingMoons.end(),a) == _contactingMoons.end()) _contactingMoons.push_back(a); } @@ -339,7 +341,8 @@ void Topology::addMoon(const uint64_t id) void Topology::removeMoon(const uint64_t id) { - Mutex::Lock _l(_lock); + Mutex::Lock _l1(_upstreams_m); + Mutex::Lock _l2(_peers_m); std::vector nm; for(std::vector::const_iterator m(_moons.begin());m!=_moons.end();++m) { @@ -365,8 +368,9 @@ void Topology::removeMoon(const uint64_t id) void Topology::clean(uint64_t now) { - Mutex::Lock _l(_lock); { + Mutex::Lock _l1(_peers_m); + Mutex::Lock _l2(_upstreams_m); Hashtable< Address,SharedPtr >::Iterator i(_peers); Address *a = (Address *)0; SharedPtr *p = (SharedPtr *)0; @@ -376,6 +380,7 @@ void Topology::clean(uint64_t now) } } { + Mutex::Lock _l(_paths_m); Hashtable< Path::HashKey,SharedPtr >::Iterator i(_paths); Path::HashKey *k = (Path::HashKey *)0; SharedPtr *p = (SharedPtr *)0; @@ -401,7 +406,7 @@ Identity Topology::_getIdentity(const Address &zta) void Topology::_memoizeUpstreams() { - // assumes _lock is locked + // assumes _upstreams_m and _peers_m are locked _upstreamAddresses.clear(); _amRoot = false; for(std::vector::const_iterator i(_planet.roots().begin());i!=_planet.roots().end();++i) { -- cgit v1.2.3