diff --git a/src/ripple/overlay/impl/OverlayImpl.h b/src/ripple/overlay/impl/OverlayImpl.h index 01cda8894a..2f33873aa6 100644 --- a/src/ripple/overlay/impl/OverlayImpl.h +++ b/src/ripple/overlay/impl/OverlayImpl.h @@ -235,10 +235,19 @@ public: for_each (UnaryFunc&& f) { std::lock_guard lock (mutex_); - for (auto const& e : ids_) + + // Iterate over a copy of the peer list because peer + // destruction can invalidate iterators. + std::vector> wp; + wp.reserve(ids_.size()); + + for (auto& x : ids_) + wp.push_back(x.second); + + for (auto& w : wp) { - if (auto sp = e.second.lock()) - f(std::move(sp)); + if (auto p = w.lock()) + f(std::move(p)); } } diff --git a/src/ripple/overlay/impl/PeerImp.cpp b/src/ripple/overlay/impl/PeerImp.cpp index 90825f38b5..1ea839d8b3 100644 --- a/src/ripple/overlay/impl/PeerImp.cpp +++ b/src/ripple/overlay/impl/PeerImp.cpp @@ -1958,14 +1958,14 @@ getPeerWithTree (OverlayImpl& ov, std::shared_ptr ret; int retScore = 0; - ov.for_each([&](std::shared_ptr const& p) + ov.for_each([&](std::shared_ptr&& p) { if (p->hasTxSet(rootHash) && p.get() != skip) { auto score = p->getScore (true); if (! ret || (score > retScore)) { - ret = p; + ret = std::move(p); retScore = score; } } @@ -1986,7 +1986,7 @@ getPeerWithLedger (OverlayImpl& ov, std::shared_ptr ret; int retScore = 0; - ov.for_each([&](std::shared_ptr const& p) + ov.for_each([&](std::shared_ptr&& p) { if (p->hasLedger(ledgerHash, ledger) && p.get() != skip) @@ -1994,7 +1994,7 @@ getPeerWithLedger (OverlayImpl& ov, auto score = p->getScore (true); if (! ret || (score > retScore)) { - ret = p; + ret = std::move(p); retScore = score; } }