From 8ef7f58d16ce7685fabde3ff6d7c9158988cb250 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Wed, 28 Sep 2005 23:58:55 +0000 Subject: [PATCH] fixed bug where some blocks weren't restored in the piece picker when the peer they were requested from disconnected. made the invariant check on policy work --- src/peer_connection.cpp | 6 +++--- src/piece_picker.cpp | 6 ++++++ src/policy.cpp | 38 +++++++++++++++++++++++++++++++++----- src/torrent.cpp | 9 +++++++-- 4 files changed, 49 insertions(+), 10 deletions(-) diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index 8ea1b8047..548dc1725 100755 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -203,7 +203,7 @@ namespace libtorrent , m_selector(sel) , m_socket(s) , m_torrent(0) - , m_attached_to_torrent(0) + , m_attached_to_torrent(false) , m_ses(ses) , m_active(false) , m_writability_monitored(false) @@ -360,7 +360,7 @@ namespace libtorrent << " *** CONNECTION CLOSED\n"; } #endif - + m_disconnecting = true; m_selector.remove(m_socket); if (m_attached_to_torrent) { @@ -2319,8 +2319,8 @@ namespace libtorrent { // check to make sure we don't have another connection with the same // info_hash and peer_id. If we do. close this connection. - m_attached_to_torrent = true; m_torrent->attach_peer(this); + m_attached_to_torrent = true; assert(m_torrent->get_policy().has_connection(this)); } diff --git a/src/piece_picker.cpp b/src/piece_picker.cpp index e628afa6c..35e21dd2e 100755 --- a/src/piece_picker.cpp +++ b/src/piece_picker.cpp @@ -650,6 +650,12 @@ namespace libtorrent if (!prefer_whole_pieces) return; assert(num_blocks > 0); +#ifdef TORRENT_VERBOSE_LOGGING + std::ofstream f("piece_picker.log", std::ios_base::app); + f << "backup_blocks: " << backup_blocks.size() << "\n" + << "used: " << std::min(num_blocks, (int)backup_blocks.size()) << "\n----\n"; +#endif + interesting_blocks.insert(interesting_blocks.end() , backup_blocks.begin(), backup_blocks.begin() + std::min(num_blocks, (int)backup_blocks.size())); diff --git a/src/policy.cpp b/src/policy.cpp index 3e2aef73a..0cc514ce0 100755 --- a/src/policy.cpp +++ b/src/policy.cpp @@ -843,8 +843,21 @@ namespace libtorrent void policy::new_connection(peer_connection& c) { assert(!c.is_local()); +/* +#ifndef NDEBUG + // avoid the invariant check to fail + peer p(address("0.0.0.0", 0), peer::not_connectable); + p.connection = &c; + m_peers.push_back(p); +#endif +*/ INVARIANT_CHECK; - +/* +#ifndef NDEBUG + // avoid the invariant check to fail + m_peers.erase(m_peers.end() - 1); +#endif +*/ // if the connection comes from the tracker, // it's probably just a NAT-check. Ignore the // num connections constraint then. @@ -1177,6 +1190,7 @@ namespace libtorrent { INVARIANT_CHECK; + assert(c.is_disconnecting()); bool unchoked = false; std::vector::iterator i = std::find_if( @@ -1219,7 +1233,8 @@ namespace libtorrent // then unchoke another peer in order to maintain // the total number of unchoked peers --m_num_unchoked; - unchoke_one_peer(); + if (m_torrent->is_seed()) seed_unchoke_one_peer(); + else unchoke_one_peer(); } } @@ -1251,15 +1266,28 @@ namespace libtorrent i != m_peers.end(); ++i) { if (!i->connection) continue; - ++connected_peers; + if (!i->connection->is_disconnecting()) + ++connected_peers; if (!i->connection->is_choked()) ++actual_unchoked; } // assert(actual_unchoked <= m_torrent->m_uploads_quota.given); assert(actual_unchoked == m_num_unchoked); - int num_torrent_peers = (int)m_torrent->num_peers(); + int num_torrent_peers = 0; + for (torrent::const_peer_iterator i = m_torrent->begin(); + i != m_torrent->end(); ++i) + { + if (i->second->is_disconnecting()) continue; + ++num_torrent_peers; + } - assert(connected_peers == num_torrent_peers); + // the second case is for when new connections + // are attached to the torrent, they are first + // added to the policy and then to the torrent. + // so in the destructor of new_connection this + // case will be used. + assert(connected_peers == num_torrent_peers + || connected_peers - 1 == num_torrent_peers); // TODO: Make sure the number of peers in m_torrent is equal // to the number of connected peers in m_peers. diff --git a/src/torrent.cpp b/src/torrent.cpp index 0769b9c6e..5827c1f46 100755 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -825,6 +825,11 @@ namespace libtorrent { m_picker->abort_download(*i); } + for (std::deque::const_iterator i = p->request_queue().begin(); + i != p->request_queue().end(); ++i) + { + m_picker->abort_download(*i); + } if (valid_metadata()) { @@ -883,13 +888,13 @@ namespace libtorrent assert(m_connections.find(p->get_socket()->sender()) == m_connections.end()); assert(!p->is_local()); - m_connections.insert(std::make_pair(p->get_socket()->sender(), p)); - detail::session_impl::connection_map::iterator i = m_ses.m_connections.find(p->get_socket()); assert(i != m_ses.m_connections.end()); m_policy->new_connection(*i->second); + + m_connections.insert(std::make_pair(p->get_socket()->sender(), p)); } void torrent::disconnect_all()