From 82a3683f7d0cee740c9706cdbf70638d2faef6ad Mon Sep 17 00:00:00 2001 From: arvidn Date: Sun, 23 Aug 2015 11:01:55 +0200 Subject: [PATCH] polish removal of web seeds logic --- include/libtorrent/torrent.hpp | 10 +++--- src/torrent.cpp | 58 ++++++++++++++++++++++------------ 2 files changed, 43 insertions(+), 25 deletions(-) diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index 48d0efe6c..23577ab0e 100644 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -559,7 +559,7 @@ namespace libtorrent #ifndef TORRENT_NO_DEPRECATE void use_interface(std::string net_interface); #endif - + void connect_to_url_seed(std::list::iterator url); bool connect_to_peer(torrent_peer* peerinfo, bool ignore_limit = false); @@ -1240,8 +1240,10 @@ namespace libtorrent void setup_peer_class(); - // The list of web seeds in this torrent. Seeds - // with fatal errors are removed from the set + // The list of web seeds in this torrent. Seeds with fatal errors are + // removed from the set. It's important that iteratores are not + // invalidated as entries are added and removed from this list, hence the + // std::list std::list m_web_seeds; #ifndef TORRENT_DISABLE_EXTENSIONS @@ -1274,7 +1276,7 @@ namespace libtorrent // these are the pieces we're currently // suggesting to peers. std::vector m_suggested_pieces; - + std::vector m_trackers; // this is an index into m_trackers diff --git a/src/torrent.cpp b/src/torrent.cpp index f7782b252..b52333975 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -6023,21 +6023,28 @@ namespace libtorrent if (web->resolving) { web->removed = true; - return; } - peer_connection* peer = static_cast(web->peer_info.connection); - if (peer) + else { - // if we have a connection for this web seed, we also need to - // disconnect it and clear its reference to the peer_info object - // that's part of the web_seed_t we're about to remove - TORRENT_ASSERT(peer->m_in_use == 1337); - peer->disconnect(boost::asio::error::operation_aborted, op_bittorrent); - peer->set_peer_info(0); - } - if (has_picker()) picker().clear_peer(&web->peer_info); +#ifndef TORRENT_DISABLE_LOGGING + debug_log("removing web seed: \"%s\"", web->url.c_str()); +#endif + + peer_connection* peer = static_cast(web->peer_info.connection); + if (peer) + { + // if we have a connection for this web seed, we also need to + // disconnect it and clear its reference to the peer_info object + // that's part of the web_seed_t we're about to remove + TORRENT_ASSERT(peer->m_in_use == 1337); + peer->disconnect(boost::asio::error::operation_aborted, op_bittorrent); + peer->set_peer_info(0); + } + if (has_picker()) picker().clear_peer(&web->peer_info); + + m_web_seeds.erase(web); + } - m_web_seeds.erase(web); update_want_tick(); } @@ -6095,7 +6102,7 @@ namespace libtorrent remove_web_seed(web); return; } - + #ifdef TORRENT_USE_OPENSSL if (protocol != "http" && protocol != "https") #else @@ -7080,6 +7087,7 @@ namespace libtorrent for (std::list::const_iterator i = m_web_seeds.begin() , end(m_web_seeds.end()); i != end; ++i) { + if (i->removed) continue; if (i->type == web_seed_entry::url_seed) url_list.push_back(i->url); else if (i->type == web_seed_entry::http_seed) @@ -10111,6 +10119,7 @@ namespace libtorrent if (w->peer_info.connection) continue; if (w->retry > aux::time_now()) continue; if (w->resolving) continue; + if (w->removed) continue; connect_to_url_seed(w); } @@ -10928,6 +10937,7 @@ namespace libtorrent , end(m_web_seeds.end()); i != end; ++i) { if (i->peer_info.banned) continue; + if (i->removed) continue; if (i->type != type) continue; ret.insert(i->url); } @@ -10940,6 +10950,7 @@ namespace libtorrent , m_web_seeds.end() , (boost::bind(&web_seed_t::url, _1) == url && boost::bind(&web_seed_t::type, _1) == type)); + if (i != m_web_seeds.end()) remove_web_seed(i); } @@ -10957,9 +10968,6 @@ namespace libtorrent TORRENT_ASSERT(i->resolving == false); -#ifndef TORRENT_DISABLE_LOGGING - debug_log("disconnect web seed: \"%s\"", i->url.c_str()); -#endif TORRENT_ASSERT(i->peer_info.connection); i->peer_info.connection = 0; } @@ -10973,11 +10981,18 @@ namespace libtorrent , boost::bind(&web_seed_t::peer_info, _1)) == p); TORRENT_ASSERT(i != m_web_seeds.end()); if (i == m_web_seeds.end()) return; - if (i->peer_info.connection) i->peer_info.connection->disconnect(ec, op, error); - if (has_picker()) picker().clear_peer(&i->peer_info); - m_web_seeds.erase(i); - update_want_tick(); - m_need_save_resume_data = true; + + peer_connection* peer = static_cast(i->peer_info.connection); + if (peer) + { + // if we have a connection for this web seed, we also need to + // disconnect it and clear its reference to the peer_info object + // that's part of the web_seed_t we're about to remove + TORRENT_ASSERT(peer->m_in_use == 1337); + peer->disconnect(ec, op, error); + peer->set_peer_info(0); + } + remove_web_seed(i); } void torrent::retry_web_seed(peer_connection* p, int retry) @@ -10990,6 +11005,7 @@ namespace libtorrent TORRENT_ASSERT(i != m_web_seeds.end()); if (i == m_web_seeds.end()) return; + if (i->removed) return; if (retry == 0) retry = settings().get_int(settings_pack::urlseed_wait_retry); i->retry = aux::time_now() + seconds(retry); }