From d5f51f60abff1c77230d77c1864f6a4fc49964a3 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Thu, 16 Feb 2012 10:06:21 +0000 Subject: [PATCH] fix issue introduced with updated disconnect-redundant logic for metadata-only seeding --- src/torrent.cpp | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/src/torrent.cpp b/src/torrent.cpp index 5b48a4d73..9ecc12702 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -3115,21 +3115,19 @@ namespace libtorrent // increase the trust point of all peers that sent // parts of this piece. std::set peers; - std::copy(downloaders.begin(), downloaders.end(), std::inserter(peers, peers.begin())); - we_have(index); - - for (peer_iterator i = m_connections.begin(); i != m_connections.end();) - { - intrusive_ptr p = *i; - ++i; - p->announce_piece(index); - } + // these policy::peer pointers are owned by m_policy and they may be + // invalidated if a peer disconnects. We cannot keep them across any + // significant operations, but we should use them right away + // ignore NULL pointers + std::remove_copy(downloaders.begin(), downloaders.end() + , std::inserter(peers, peers.begin()), (policy::peer*)0); for (std::set::iterator i = peers.begin() , end(peers.end()); i != end; ++i) { policy::peer* p = static_cast(*i); + TORRENT_ASSERT(p != 0); if (p == 0) continue; TORRENT_ASSERT(p->in_use); p->on_parole = false; @@ -3144,6 +3142,21 @@ namespace libtorrent } } + // announcing a piece may invalidate the policy::peer pointers + // so we can't use them anymore + + downloaders.clear(); + peers.clear(); + + we_have(index); + + for (peer_iterator i = m_connections.begin(); i != m_connections.end();) + { + intrusive_ptr p = *i; + ++i; + p->announce_piece(index); + } + if (settings().max_sparse_regions > 0 && m_picker->sparse_regions() > settings().max_sparse_regions) { @@ -5579,6 +5592,11 @@ namespace libtorrent // any of the peers. m_override_resume_data = true; + // we have to initialize the torrent before we start + // disconnecting redundant peers, otherwise we'll think + // we're a seed, because we have all 0 pieces + init(); + // disconnect redundant peers for (std::set::iterator i = m_connections.begin() , end(m_connections.end()); i != end;) @@ -5587,8 +5605,6 @@ namespace libtorrent (*p)->disconnect_if_redundant(); } - init(); - return true; }