From 3435da235d7a68396ca28ef55d6a231d1244d92a Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Sat, 9 Apr 2011 23:57:56 +0000 Subject: [PATCH] make is_upload_only() be accurate and deal with super seeding special case only where necessary. Fix pointless assert in invariant check --- Jamfile | 2 ++ include/libtorrent/torrent.hpp | 3 +-- src/bt_peer_connection.cpp | 17 +++++++++++++++-- src/peer_connection.cpp | 22 +++++++++++----------- src/torrent.cpp | 21 ++++++++++++--------- 5 files changed, 41 insertions(+), 24 deletions(-) diff --git a/Jamfile b/Jamfile index f7c892370..a4db961dc 100755 --- a/Jamfile +++ b/Jamfile @@ -13,6 +13,8 @@ CXXFLAGS = [ modules.peek : CXXFLAGS ] ; LDFLAGS = [ modules.peek : LDFLAGS ] ; ECHO "BOOST_ROOT =" $(BOOST_ROOT) ; +ECHO "CXXFLAGS =" $(CXXFLAGS) ; +ECHO "LDFLAGS =" $(LDFLAGS) ; ECHO "OS =" [ os.name ] ; if $(BOOST_ROOT) diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index 0284345b9..e8c5e0b28 100644 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -170,8 +170,7 @@ namespace libtorrent void set_upload_mode(bool b); bool upload_mode() const { return m_upload_mode || m_graceful_pause_mode; } - bool is_upload_only() const - { return (is_finished() || upload_mode()) && !super_seeding(); } + bool is_upload_only() const { return is_finished() || upload_mode(); } int seed_rank(session_settings const& s) const; diff --git a/src/bt_peer_connection.cpp b/src/bt_peer_connection.cpp index 5c0fe1749..74db6d37a 100644 --- a/src/bt_peer_connection.cpp +++ b/src/bt_peer_connection.cpp @@ -1897,7 +1897,12 @@ namespace libtorrent char msg[7] = {0, 0, 0, 3, msg_extended}; char* ptr = msg + 5; detail::write_uint8(m_upload_only_id, ptr); - detail::write_uint8(t->is_upload_only(), ptr); + // if we're super seeding, we don't want to make peers + // think that we only have a single piece and is upload + // only, since they might disconnect immediately when + // they have downloaded a single piece, although we'll + // make another piece available + detail::write_uint8(t->is_upload_only() && !t->super_seeding(), ptr); send_buffer(msg, sizeof(msg)); } @@ -2150,7 +2155,15 @@ namespace libtorrent // we're upload only, since it might make peers disconnect // don't tell anyone we're upload only when in share mode // we want to stay connected to seeds - if (t->is_upload_only() && !t->share_mode() && (!m_ses.settings().lazy_bitfields + // if we're super seeding, we don't want to make peers + // think that we only have a single piece and is upload + // only, since they might disconnect immediately when + // they have downloaded a single piece, although we'll + // make another piece available + if (t->is_upload_only() + && !t->share_mode() + && !t->super_seeding() + && (!m_ses.settings().lazy_bitfields #ifndef TORRENT_DISABLE_ENCRYPTION || m_encrypted #endif diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index 9543cc0d3..a35e7d4f9 100644 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -574,7 +574,7 @@ namespace libtorrent if (!t->ready_for_connections()) return; bool interested = false; - if (!t->is_finished()) + if (!t->is_upload_only()) { piece_picker const& p = t->picker(); int num_pieces = p.num_pieces(); @@ -768,7 +768,7 @@ namespace libtorrent on_metadata(); if (m_disconnecting) return; - if (!t->is_finished()) + if (!t->is_upload_only()) t->get_policy().peer_is_interesting(*this); return; @@ -830,7 +830,7 @@ namespace libtorrent m_upload_only = true; t->peer_has_all(); - if (t->is_finished()) send_not_interested(); + if (t->is_upload_only()) send_not_interested(); else t->get_policy().peer_is_interesting(*this); return; } @@ -1817,7 +1817,7 @@ namespace libtorrent m_have_piece.set_all(); m_num_pieces = num_pieces; t->peer_has_all(); - if (!t->is_finished()) + if (!t->is_upload_only()) t->get_policy().peer_is_interesting(*this); disconnect_if_redundant(); @@ -2626,7 +2626,7 @@ namespace libtorrent t->peer_has_all(); // if we're finished, we're not interested - if (t->is_finished()) send_not_interested(); + if (t->is_upload_only()) send_not_interested(); else t->get_policy().peer_is_interesting(*this); disconnect_if_redundant(); @@ -3945,7 +3945,7 @@ namespace libtorrent && m_reading_bytes == 0 && !m_choked && m_peer_interested - && t && t->is_finished() + && t && t->is_upload_only() && d > seconds(20)) { #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING @@ -4072,7 +4072,7 @@ namespace libtorrent // maintain the share ratio given by m_ratio // with all peers. - if (t->is_finished() || is_choked() || t->ratio() == 0.0f) + if (t->is_upload_only() || is_choked() || t->ratio() == 0.0f) { // if we have downloaded more than one piece more // than we have uploaded OR if we are a seed @@ -4225,7 +4225,7 @@ namespace libtorrent // assume half of the cache is write cache if we're downloading // this torrent as well int cache_size = m_ses.m_settings.cache_size / num_uploads; - if (!t->is_finished()) cache_size /= 2; + if (!t->is_upload_only()) cache_size /= 2; // cache_size is the amount of cache we have per peer. The // cache line should not be greater than this @@ -4386,7 +4386,7 @@ namespace libtorrent shared_ptr t = m_torrent.lock(); int priority; if (m_ses.m_settings.choking_algorithm == session_settings::bittyrant_choker - && !t->is_upload_only()) + && !t->upload_mode() && !t->is_upload_only()) { // when we use the bittyrant choker, the priority of a peer // is decided based on the estimated reciprocation rate and @@ -5451,7 +5451,7 @@ namespace libtorrent if (m_ses.settings().close_redundant_connections && !t->share_mode()) { // make sure upload only peers are disconnected - if (t->is_finished() && m_upload_only) + if (t->is_upload_only() && m_upload_only) TORRENT_ASSERT(m_disconnect_started); if (m_upload_only && !m_interesting @@ -5463,7 +5463,7 @@ namespace libtorrent if (!m_disconnect_started && m_initialized) { // none of this matters if we're disconnecting anyway - if (t->is_finished()) + if (t->is_upload_only()) TORRENT_ASSERT(!m_interesting); if (is_seed()) TORRENT_ASSERT(m_upload_only); diff --git a/src/torrent.cpp b/src/torrent.cpp index b100ccd31..0247a4790 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -940,12 +940,20 @@ namespace libtorrent void torrent::send_upload_only() { #ifndef TORRENT_DISABLE_EXTENSIONS - for (std::set::iterator i = m_connections.begin() - , end(m_connections.end()); i != end; ++i) + if (share_mode()) return; + if (super_seeding()) return; + + for (std::set::iterator i = m_connections.begin(); + i != m_connections.end();) { - if ((*i)->type() != peer_connection::bittorrent_connection) continue; + // since the call to disconnect_if_redundant() may + // delete the entry from this container, make sure + // to increment the iterator early bt_peer_connection* p = (bt_peer_connection*)*i; - p->write_upload_only(); + ++i; + if (p->type() == peer_connection::bittorrent_connection) + p->write_upload_only(); + p->disconnect_if_redundant(); } #endif } @@ -5601,11 +5609,6 @@ namespace libtorrent TORRENT_ASSERT(found >= 1); } - if (is_finished()) - { - TORRENT_ASSERT(is_upload_only()); - } - TORRENT_ASSERT(m_resume_entry.type() == lazy_entry::dict_t || m_resume_entry.type() == lazy_entry::none_t);