fix race condition when resolving the hostname of a web seed and removing it

This commit is contained in:
Arvid Norberg 2011-04-29 08:09:03 +00:00
parent c8434f56eb
commit 0eb7505ad9
3 changed files with 38 additions and 9 deletions

View File

@ -366,7 +366,7 @@ namespace libtorrent
std::list<web_seed_entry>::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<web_seed_entry>::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<web_seed_entry>::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

View File

@ -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;

View File

@ -3843,6 +3843,16 @@ namespace libtorrent
m_connections.erase(i);
}
void torrent::remove_web_seed(std::list<web_seed_entry>::iterator web)
{
if (web->resolving)
{
web->removed = true;
return;
}
m_web_seeds.erase(web);
}
void torrent::connect_to_url_seed(std::list<web_seed_entry>::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;