diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index e5b7b5686..2efbb735b 100644 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -366,7 +366,7 @@ namespace libtorrent std::list::iterator i = std::find_if(m_web_seeds.begin(), m_web_seeds.end() , (boost::bind(&web_seed_entry::url, _1) == url && boost::bind(&web_seed_entry::type, _1) == type)); - if (i != m_web_seeds.end()) m_web_seeds.erase(i); + if (i != m_web_seeds.end()) remove_web_seed(i); } void disconnect_web_seed(peer_connection* p) @@ -630,6 +630,10 @@ namespace libtorrent void on_proxy_name_lookup(error_code const& e, tcp::resolver::iterator i , std::list::iterator url); + // remove a web seed, or schedule it for removal in case there + // are outstanding operations on it + void remove_web_seed(std::list::iterator web); + // this is called when the torrent has finished. i.e. // all the pieces we have not filtered have been downloaded. // If no pieces are filtered, this is called first and then diff --git a/include/libtorrent/torrent_info.hpp b/include/libtorrent/torrent_info.hpp index 7930fccb9..23170fc6d 100644 --- a/include/libtorrent/torrent_info.hpp +++ b/include/libtorrent/torrent_info.hpp @@ -186,7 +186,8 @@ namespace libtorrent , headers_t const& extra_headers_ = headers_t()) : url(url_), type(type_) , auth(auth_), extra_headers(extra_headers_) - , retry(time_now()), resolving(false), connection(0) + , retry(time_now()), resolving(false), removed(false) + , connection(0) {} bool operator==(web_seed_entry const& e) const @@ -211,6 +212,12 @@ namespace libtorrent // hostname of this URL bool resolving; + // if the user wanted to remove this while + // we were resolving it. In this case, we set + // the removed flag to true, to make the resolver + // callback remove it + bool removed; + tcp::endpoint endpoint; peer_connection* connection; diff --git a/src/torrent.cpp b/src/torrent.cpp index 06c90a8df..fa761fd64 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -3843,6 +3843,16 @@ namespace libtorrent m_connections.erase(i); } + void torrent::remove_web_seed(std::list::iterator web) + { + if (web->resolving) + { + web->removed = true; + return; + } + m_web_seeds.erase(web); + } + void torrent::connect_to_url_seed(std::list::iterator web) { TORRENT_ASSERT(m_ses.is_network_thread()); @@ -3875,7 +3885,7 @@ namespace libtorrent url_seed_alert(get_handle(), web->url, ec)); } // never try it again - m_web_seeds.erase(web); + remove_web_seed(web); return; } @@ -3891,7 +3901,7 @@ namespace libtorrent url_seed_alert(get_handle(), web->url, errors::unsupported_url_protocol)); } // never try it again - m_web_seeds.erase(web); + remove_web_seed(web); return; } @@ -3903,7 +3913,7 @@ namespace libtorrent url_seed_alert(get_handle(), web->url, errors::invalid_hostname)); } // never try it again - m_web_seeds.erase(web); + remove_web_seed(web); return; } @@ -3915,7 +3925,7 @@ namespace libtorrent url_seed_alert(get_handle(), web->url, errors::invalid_port)); } // never try it again - m_web_seeds.erase(web); + remove_web_seed(web); return; } @@ -3927,7 +3937,7 @@ namespace libtorrent url_seed_alert(get_handle(), web->url, errors::port_blocked)); } // never try it again - m_web_seeds.erase(web); + remove_web_seed(web); return; } @@ -3987,7 +3997,7 @@ namespace libtorrent // the name lookup failed for the http host. Don't try // this host again - m_web_seeds.erase(web); + remove_web_seed(web); return; } @@ -4009,7 +4019,7 @@ namespace libtorrent m_ses.m_alerts.post_alert( url_seed_alert(get_handle(), web->url, ec)); } - m_web_seeds.erase(web); + remove_web_seed(web); return; } @@ -4039,6 +4049,14 @@ namespace libtorrent (*m_ses.m_logger) << time_now_string() << " completed resolve: " << web->url << "\n"; #endif web->resolving = false; + if (web->removed) + { +#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING + (*m_ses.m_logger) << time_now_string() << " removed web seed\n"; +#endif + remove_web_seed(web); + return; + } if (m_abort) return;