From d0dab83104f8107e361892ac8308632b5fdfd10f Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Sat, 2 Oct 2010 21:01:11 +0000 Subject: [PATCH] potential fix for long standing invariant check failure --- src/peer_connection.cpp | 26 ++++++++++++++++++++++---- src/policy.cpp | 1 + 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index 964186a4f..0b42d9a05 100644 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -808,6 +808,8 @@ namespace libtorrent } #endif TORRENT_ASSERT(!m_ses.has_peer(this)); + TORRENT_ASSERT(m_request_queue.empty()); + TORRENT_ASSERT(m_download_queue.empty()); #ifdef TORRENT_DEBUG for (aux::session_impl::torrent_map::const_iterator i = m_ses.m_torrents.begin() , end(m_ses.m_torrents.end()); i != end; ++i) @@ -2716,6 +2718,7 @@ namespace libtorrent boost::shared_ptr t = m_torrent.lock(); TORRENT_ASSERT(t); + TORRENT_ASSERT(!m_disconnecting); TORRENT_ASSERT(t->valid_metadata()); TORRENT_ASSERT(block.piece_index >= 0); TORRENT_ASSERT(block.piece_index < t->torrent_file().num_pieces()); @@ -2729,6 +2732,7 @@ namespace libtorrent , block) == m_request_queue.end()); if (t->upload_mode()) return false; + if (m_disconnecting) return false; piece_picker::piece_state_t state; peer_speed_t speed = peer_speed(); @@ -3042,6 +3046,8 @@ namespace libtorrent boost::shared_ptr t = m_torrent.lock(); TORRENT_ASSERT(t); + if (m_disconnecting) return; + if ((int)m_download_queue.size() >= m_desired_queue_size || t->upload_mode()) return; @@ -5066,7 +5072,15 @@ namespace libtorrent } #ifdef TORRENT_DEBUG - struct peer_count_t { int num_peers; int num_peers_with_timeouts; int num_peers_with_nowant; }; + struct peer_count_t + { + peer_count_t(): num_peers(0), num_peers_with_timeouts(0), num_peers_with_nowant(0), num_not_requested(0) {} + int num_peers; + int num_peers_with_timeouts; + int num_peers_with_nowant; + int num_not_requested; + std::vector peers; + }; void peer_connection::check_invariant() const { @@ -5201,6 +5215,8 @@ namespace libtorrent ++num_requests[i->block].num_peers; ++num_requests[i->block].num_peers_with_timeouts; ++num_requests[i->block].num_peers_with_nowant; + ++num_requests[i->block].num_not_requested; + num_requests[i->block].peers.push_back(&p); } for (std::vector::const_iterator i = p.download_queue().begin() , end(p.download_queue().end()); i != end; ++i) @@ -5208,15 +5224,17 @@ namespace libtorrent if (!i->not_wanted && !i->timed_out) ++num_requests[i->block].num_peers; if (i->timed_out) ++num_requests[i->block].num_peers_with_timeouts; if (i->not_wanted) ++num_requests[i->block].num_peers_with_nowant; + num_requests[i->block].peers.push_back(&p); } } for (std::map::iterator i = num_requests.begin() , end(num_requests.end()); i != end; ++i) { piece_block b = i->first; - int count = i->second.num_peers; - int count_with_timeouts = i->second.num_peers_with_timeouts; - int count_with_nowant = i->second.num_peers_with_nowant; + peer_count_t const& pc = i->second; + int count = pc.num_peers; + int count_with_timeouts = pc.num_peers_with_timeouts; + int count_with_nowant = pc.num_peers_with_nowant; int picker_count = t->picker().num_peers(b); if (!t->picker().is_downloaded(b)) TORRENT_ASSERT(picker_count == count); diff --git a/src/policy.cpp b/src/policy.cpp index 1d559a1cf..e74905ea9 100644 --- a/src/policy.cpp +++ b/src/policy.cpp @@ -129,6 +129,7 @@ namespace libtorrent if (t.is_seed()) return; if (c.no_download()) return; if (t.upload_mode()) return; + if (c.is_disconnecting()) return; // don't request pieces before we have the metadata if (!t.valid_metadata()) return;