fix race condition (rev 1561)
This commit is contained in:
parent
b7f0447228
commit
ff073dc4fb
|
@ -194,11 +194,10 @@ namespace libtorrent
|
|||
, address bind_interface
|
||||
, boost::weak_ptr<request_callback> r);
|
||||
|
||||
request_callback& requester();
|
||||
boost::shared_ptr<request_callback> requester();
|
||||
virtual ~tracker_connection() {}
|
||||
|
||||
tracker_request const& tracker_req() const { return m_req; }
|
||||
bool has_requester() const { return !m_requester.expired(); }
|
||||
|
||||
void fail(int code, char const* msg);
|
||||
void fail_timeout();
|
||||
|
|
|
@ -459,14 +459,16 @@ namespace libtorrent
|
|||
m_send_buffer += "\r\n\r\n";
|
||||
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
if (has_requester())
|
||||
|
||||
boost::shared_ptr<request_callback> cb = requester();
|
||||
if (cb)
|
||||
{
|
||||
requester().debug_log("==> TRACKER_REQUEST [ str: " + m_send_buffer + " ]");
|
||||
cb->debug_log("==> TRACKER_REQUEST [ str: " + m_send_buffer + " ]");
|
||||
std::stringstream info_hash_str;
|
||||
info_hash_str << req.info_hash;
|
||||
requester().debug_log("info_hash: "
|
||||
cb->debug_log("info_hash: "
|
||||
+ boost::lexical_cast<std::string>(req.info_hash));
|
||||
requester().debug_log("name lookup: " + hostname);
|
||||
cb->debug_log("name lookup: " + hostname);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -491,8 +493,9 @@ namespace libtorrent
|
|||
void http_tracker_connection::name_lookup(asio::error_code const& error
|
||||
, tcp::resolver::iterator i) try
|
||||
{
|
||||
boost::shared_ptr<request_callback> cb = requester();
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
if (has_requester()) requester().debug_log("tracker name lookup handler called");
|
||||
if (cb) cb->debug_log("tracker name lookup handler called");
|
||||
#endif
|
||||
if (error == asio::error::operation_aborted) return;
|
||||
if (m_timed_out) return;
|
||||
|
@ -504,7 +507,7 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
if (has_requester()) requester().debug_log("tracker name lookup successful");
|
||||
if (cb) cb->debug_log("tracker name lookup successful");
|
||||
#endif
|
||||
restart_read_timeout();
|
||||
|
||||
|
@ -519,11 +522,11 @@ namespace libtorrent
|
|||
if (target == end)
|
||||
{
|
||||
assert(target_address.address().is_v4() != bind_interface().is_v4());
|
||||
if (has_requester())
|
||||
if (cb)
|
||||
{
|
||||
std::string tracker_address_type = target_address.address().is_v4() ? "IPv4" : "IPv6";
|
||||
std::string bind_address_type = bind_interface().is_v4() ? "IPv4" : "IPv6";
|
||||
requester().tracker_warning("the tracker only resolves to an "
|
||||
cb->tracker_warning("the tracker only resolves to an "
|
||||
+ tracker_address_type + " address, and you're listening on an "
|
||||
+ bind_address_type + " socket. This may prevent you from receiving incoming connections.");
|
||||
}
|
||||
|
@ -533,7 +536,7 @@ namespace libtorrent
|
|||
target_address = *target;
|
||||
}
|
||||
|
||||
if (has_requester()) requester().m_tracker_address = target_address;
|
||||
if (cb) cb->m_tracker_address = target_address;
|
||||
m_socket = instantiate_connection(m_name_lookup.io_service(), m_proxy);
|
||||
|
||||
if (m_proxy.type == proxy_settings::http
|
||||
|
@ -574,7 +577,8 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
if (has_requester()) requester().debug_log("tracker connection successful");
|
||||
boost::shared_ptr<request_callback> cb = requester();
|
||||
if (cb) cb->debug_log("tracker connection successful");
|
||||
#endif
|
||||
|
||||
restart_read_timeout();
|
||||
|
@ -598,7 +602,8 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
if (has_requester()) requester().debug_log("tracker send data completed");
|
||||
boost::shared_ptr<request_callback> cb = requester();
|
||||
if (cb) cb->debug_log("tracker send data completed");
|
||||
#endif
|
||||
restart_read_timeout();
|
||||
assert(m_buffer.size() - m_recv_pos > 0);
|
||||
|
@ -634,7 +639,8 @@ namespace libtorrent
|
|||
restart_read_timeout();
|
||||
assert(bytes_transferred > 0);
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
if (has_requester()) requester().debug_log("tracker connection reading "
|
||||
boost::shared_ptr<request_callback> cb = requester();
|
||||
if (cb) cb->debug_log("tracker connection reading "
|
||||
+ boost::lexical_cast<std::string>(bytes_transferred));
|
||||
#endif
|
||||
|
||||
|
@ -701,6 +707,8 @@ namespace libtorrent
|
|||
|
||||
std::string location = m_parser.header<std::string>("location");
|
||||
|
||||
boost::shared_ptr<request_callback> cb = requester();
|
||||
|
||||
if (m_parser.status_code() >= 300 && m_parser.status_code() < 400)
|
||||
{
|
||||
if (location.empty())
|
||||
|
@ -720,9 +728,9 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
if (has_requester()) requester().debug_log("Redirecting to \"" + location + "\"");
|
||||
if (cb) cb->debug_log("Redirecting to \"" + location + "\"");
|
||||
#endif
|
||||
if (has_requester()) requester().tracker_warning("Redirecting to \"" + location + "\"");
|
||||
if (cb) cb->tracker_warning("Redirecting to \"" + location + "\"");
|
||||
tracker_request req = tracker_req();
|
||||
|
||||
req.url = location;
|
||||
|
@ -745,20 +753,18 @@ namespace libtorrent
|
|||
std::string content_encoding = m_parser.header<std::string>("content-encoding");
|
||||
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
if (has_requester()) requester().debug_log("content-encoding: \"" + content_encoding + "\"");
|
||||
if (cb) cb->debug_log("content-encoding: \"" + content_encoding + "\"");
|
||||
#endif
|
||||
|
||||
if (content_encoding == "gzip" || content_encoding == "x-gzip")
|
||||
{
|
||||
boost::shared_ptr<request_callback> r = m_requester.lock();
|
||||
|
||||
if (!r)
|
||||
if (!cb)
|
||||
{
|
||||
close();
|
||||
return;
|
||||
}
|
||||
m_buffer.erase(m_buffer.begin(), m_buffer.begin() + m_parser.body_start());
|
||||
if (inflate_gzip(m_buffer, tracker_request(), r.get(),
|
||||
if (inflate_gzip(m_buffer, tracker_request(), cb.get(),
|
||||
m_settings.tracker_maximum_response_length))
|
||||
{
|
||||
close();
|
||||
|
@ -835,7 +841,8 @@ namespace libtorrent
|
|||
|
||||
void http_tracker_connection::parse(entry const& e)
|
||||
{
|
||||
if (!has_requester()) return;
|
||||
boost::shared_ptr<request_callback> cb = requester();
|
||||
if (!cb) return;
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -852,8 +859,7 @@ namespace libtorrent
|
|||
try
|
||||
{
|
||||
entry const& warning = e["warning message"];
|
||||
if (has_requester())
|
||||
requester().tracker_warning(warning.string());
|
||||
cb->tracker_warning(warning.string());
|
||||
}
|
||||
catch(type_error const&) {}
|
||||
|
||||
|
@ -867,7 +873,7 @@ namespace libtorrent
|
|||
entry scrape_data = e["files"][ih];
|
||||
int complete = scrape_data["complete"].integer();
|
||||
int incomplete = scrape_data["incomplete"].integer();
|
||||
requester().tracker_response(tracker_request(), peer_list, 0, complete
|
||||
cb->tracker_response(tracker_request(), peer_list, 0, complete
|
||||
, incomplete);
|
||||
return;
|
||||
}
|
||||
|
@ -914,16 +920,16 @@ namespace libtorrent
|
|||
try { incomplete = e["incomplete"].integer(); }
|
||||
catch(type_error&) {}
|
||||
|
||||
requester().tracker_response(tracker_request(), peer_list, interval, complete
|
||||
cb->tracker_response(tracker_request(), peer_list, interval, complete
|
||||
, incomplete);
|
||||
}
|
||||
catch(type_error& e)
|
||||
{
|
||||
requester().tracker_request_error(tracker_request(), m_parser.status_code(), e.what());
|
||||
cb->tracker_request_error(tracker_request(), m_parser.status_code(), e.what());
|
||||
}
|
||||
catch(std::runtime_error& e)
|
||||
{
|
||||
requester().tracker_request_error(tracker_request(), m_parser.status_code(), e.what());
|
||||
cb->tracker_request_error(tracker_request(), m_parser.status_code(), e.what());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -365,23 +365,22 @@ namespace libtorrent
|
|||
, m_req(req)
|
||||
{}
|
||||
|
||||
request_callback& tracker_connection::requester()
|
||||
boost::shared_ptr<request_callback> tracker_connection::requester()
|
||||
{
|
||||
boost::shared_ptr<request_callback> r = m_requester.lock();
|
||||
assert(r);
|
||||
return *r;
|
||||
return m_requester.lock();
|
||||
}
|
||||
|
||||
void tracker_connection::fail(int code, char const* msg)
|
||||
{
|
||||
if (has_requester()) requester().tracker_request_error(
|
||||
m_req, code, msg);
|
||||
boost::shared_ptr<request_callback> cb = requester();
|
||||
if (cb) cb->tracker_request_error(m_req, code, msg);
|
||||
close();
|
||||
}
|
||||
|
||||
void tracker_connection::fail_timeout()
|
||||
{
|
||||
if (has_requester()) requester().tracker_request_timed_out(m_req);
|
||||
boost::shared_ptr<request_callback> cb = requester();
|
||||
if (cb) cb->tracker_request_timed_out(m_req);
|
||||
close();
|
||||
}
|
||||
|
||||
|
@ -548,7 +547,8 @@ namespace libtorrent
|
|||
|
||||
m_connections.push_back(con);
|
||||
|
||||
if (con->has_requester()) con->requester().m_manager = this;
|
||||
boost::shared_ptr<request_callback> cb = con->requester();
|
||||
if (cb) cb->m_manager = this;
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
|
|
|
@ -110,8 +110,9 @@ namespace libtorrent
|
|||
return;
|
||||
}
|
||||
|
||||
boost::shared_ptr<request_callback> cb = requester();
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
if (has_requester()) requester().debug_log("udp tracker name lookup successful");
|
||||
if (cb) cb->debug_log("udp tracker name lookup successful");
|
||||
#endif
|
||||
restart_read_timeout();
|
||||
|
||||
|
@ -126,11 +127,11 @@ namespace libtorrent
|
|||
if (target == end)
|
||||
{
|
||||
assert(target_address.address().is_v4() != bind_interface().is_v4());
|
||||
if (has_requester())
|
||||
if (cb)
|
||||
{
|
||||
std::string tracker_address_type = target_address.address().is_v4() ? "IPv4" : "IPv6";
|
||||
std::string bind_address_type = bind_interface().is_v4() ? "IPv4" : "IPv6";
|
||||
requester().tracker_warning("the tracker only resolves to an "
|
||||
cb->tracker_warning("the tracker only resolves to an "
|
||||
+ tracker_address_type + " address, and you're listening on an "
|
||||
+ bind_address_type + " socket. This may prevent you from receiving incoming connections.");
|
||||
}
|
||||
|
@ -140,7 +141,7 @@ namespace libtorrent
|
|||
target_address = *target;
|
||||
}
|
||||
|
||||
if (has_requester()) requester().m_tracker_address = tcp::endpoint(target_address.address(), target_address.port());
|
||||
if (cb) cb->m_tracker_address = tcp::endpoint(target_address.address(), target_address.port());
|
||||
m_target = target_address;
|
||||
m_socket.reset(new datagram_socket(m_name_lookup.io_service()));
|
||||
m_socket->open(target_address.protocol());
|
||||
|
@ -163,9 +164,10 @@ namespace libtorrent
|
|||
void udp_tracker_connection::send_udp_connect()
|
||||
{
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
if (has_requester())
|
||||
boost::shared_ptr<request_callback> cb = requester();
|
||||
if (cb)
|
||||
{
|
||||
requester().debug_log("==> UDP_TRACKER_CONNECT ["
|
||||
cb->debug_log("==> UDP_TRACKER_CONNECT ["
|
||||
+ lexical_cast<std::string>(tracker_req().info_hash) + "]");
|
||||
}
|
||||
#endif
|
||||
|
@ -259,9 +261,10 @@ namespace libtorrent
|
|||
m_connection_id = detail::read_int64(ptr);
|
||||
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
if (has_requester())
|
||||
boost::shared_ptr<request_callback> cb = requester();
|
||||
if (cb)
|
||||
{
|
||||
requester().debug_log("<== UDP_TRACKER_CONNECT_RESPONSE ["
|
||||
cb->debug_log("<== UDP_TRACKER_CONNECT_RESPONSE ["
|
||||
+ lexical_cast<std::string>(m_connection_id) + "]");
|
||||
}
|
||||
#endif
|
||||
|
@ -321,9 +324,10 @@ namespace libtorrent
|
|||
detail::write_uint16(0, out);
|
||||
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
if (has_requester())
|
||||
boost::shared_ptr<request_callback> cb = requester();
|
||||
if (cb)
|
||||
{
|
||||
requester().debug_log("==> UDP_TRACKER_ANNOUNCE ["
|
||||
cb->debug_log("==> UDP_TRACKER_ANNOUNCE ["
|
||||
+ lexical_cast<std::string>(req.info_hash) + "]");
|
||||
}
|
||||
#endif
|
||||
|
@ -431,14 +435,15 @@ namespace libtorrent
|
|||
return;
|
||||
}
|
||||
|
||||
boost::shared_ptr<request_callback> cb = requester();
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
if (has_requester())
|
||||
if (cb)
|
||||
{
|
||||
requester().debug_log("<== UDP_TRACKER_ANNOUNCE_RESPONSE");
|
||||
cb->debug_log("<== UDP_TRACKER_ANNOUNCE_RESPONSE");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!has_requester())
|
||||
if (!cb)
|
||||
{
|
||||
m_man.remove_request(this);
|
||||
return;
|
||||
|
@ -459,7 +464,7 @@ namespace libtorrent
|
|||
peer_list.push_back(e);
|
||||
}
|
||||
|
||||
requester().tracker_response(tracker_req(), peer_list, interval
|
||||
cb->tracker_response(tracker_req(), peer_list, interval
|
||||
, complete, incomplete);
|
||||
|
||||
m_man.remove_request(this);
|
||||
|
@ -534,14 +539,15 @@ namespace libtorrent
|
|||
/*int downloaded = */detail::read_int32(buf);
|
||||
int incomplete = detail::read_int32(buf);
|
||||
|
||||
if (!has_requester())
|
||||
boost::shared_ptr<request_callback> cb = requester();
|
||||
if (!cb)
|
||||
{
|
||||
m_man.remove_request(this);
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<peer_entry> peer_list;
|
||||
requester().tracker_response(tracker_req(), peer_list, 0
|
||||
cb->tracker_response(tracker_req(), peer_list, 0
|
||||
, complete, incomplete);
|
||||
|
||||
m_man.remove_request(this);
|
||||
|
|
Loading…
Reference in New Issue