mark some expensive parts of invariant checks as expensive and disabled by default. introduce undead_peers to destruct all peer_connections in the network thread. they hang around while waiting for all outstanding disk jobs to complete. make the asio-debugging output a bit prettier

This commit is contained in:
Arvid Norberg 2013-12-05 07:42:32 +00:00
parent 88e4e0a97b
commit 4f189e921d
4 changed files with 27 additions and 2 deletions

View File

@ -748,6 +748,14 @@ namespace libtorrent
// they would linger and stall or hang session shutdown // they would linger and stall or hang session shutdown
std::set<boost::shared_ptr<socket_type> > m_incoming_sockets; std::set<boost::shared_ptr<socket_type> > m_incoming_sockets;
// peer connections are put here when disconnected to avoid
// race conditions with the disk thread. It's important that
// peer connections are destructed from the network thread,
// once a peer is disconnected, it's put in this list and
// every second their refcount is checked, and if it's 1,
// they are deleted (from the network thread)
std::vector<boost::intrusive_ptr<peer_connection> > m_undead_peers;
// filters incoming connections // filters incoming connections
ip_filter m_ip_filter; ip_filter m_ip_filter;

View File

@ -5883,6 +5883,7 @@ namespace libtorrent
TORRENT_ASSERT(m_upload_only); TORRENT_ASSERT(m_upload_only);
} }
#ifdef TORRENT_EXPENSIVE_INVARIANT_CHECKS
if (t->has_picker()) if (t->has_picker())
{ {
std::map<piece_block, peer_count_t> num_requests; std::map<piece_block, peer_count_t> num_requests;
@ -5926,7 +5927,7 @@ namespace libtorrent
TORRENT_ASSERT(picker_count == count); TORRENT_ASSERT(picker_count == count);
} }
} }
#ifdef TORRENT_EXPENSIVE_INVARIANT_CHECKS
if (m_peer_info && type() == bittorrent_connection) if (m_peer_info && type() == bittorrent_connection)
{ {
policy::const_iterator i = t->get_policy().begin_peer(); policy::const_iterator i = t->get_policy().begin_peer();

View File

@ -1746,6 +1746,8 @@ namespace aux {
m_udp_socket.close(); m_udp_socket.close();
m_external_udp_port = 0; m_external_udp_port = 0;
m_undead_peers.clear();
#ifndef TORRENT_DISABLE_GEO_IP #ifndef TORRENT_DISABLE_GEO_IP
if (m_asnum_db) GeoIP_delete(m_asnum_db); if (m_asnum_db) GeoIP_delete(m_asnum_db);
if (m_country_db) GeoIP_delete(m_country_db); if (m_country_db) GeoIP_delete(m_country_db);
@ -2898,6 +2900,12 @@ retry:
{ {
TORRENT_ASSERT(is_network_thread()); TORRENT_ASSERT(is_network_thread());
// someone else is holding a reference, it's important that
// it's destructed from the network thread. Make sure the
// last reference is held by the network thread.
if (!p->refcount() == 1)
m_undead_peers.push_back((peer_connection*)p);
// too expensive // too expensive
// INVARIANT_CHECK; // INVARIANT_CHECK;
@ -3082,6 +3090,12 @@ retry:
update_dht_announce_interval(); update_dht_announce_interval();
#endif #endif
// remove undead peers that only have this list as their reference keeping them alive
std::vector<boost::intrusive_ptr<peer_connection> >::iterator i = std::remove_if(
m_undead_peers.begin(), m_undead_peers.end()
, boost::bind(&peer_connection::refcount, _1) == 1);
m_undead_peers.erase(i, m_undead_peers.end());
int tick_interval_ms = total_milliseconds(now - m_last_second_tick); int tick_interval_ms = total_milliseconds(now - m_last_second_tick);
m_last_second_tick = now; m_last_second_tick = now;
m_tick_residual += tick_interval_ms - 1000; m_tick_residual += tick_interval_ms - 1000;
@ -5828,7 +5842,7 @@ retry:
{ {
sleep(1000); sleep(1000);
++counter; ++counter;
printf("\n==== Waiting to shut down: %d ==== conn-queue: %d connecting: %d timeout (next: %f max: %f)\n\n" printf("\x1b[2J\x1b[0;0H\x1b[33m==== Waiting to shut down: %d ==== conn-queue: %d connecting: %d timeout (next: %f max: %f)\x1b[0m\n\n"
, counter, m_half_open.size(), m_half_open.num_connecting(), m_half_open.next_timeout() , counter, m_half_open.size(), m_half_open.num_connecting(), m_half_open.next_timeout()
, m_half_open.max_timeout()); , m_half_open.max_timeout());
} }

View File

@ -6579,6 +6579,7 @@ namespace libtorrent
else else
TORRENT_ASSERT(m_queued_for_checking); TORRENT_ASSERT(m_queued_for_checking);
#ifdef TORRENT_EXPENSIVE_INVARIANT_CHECKS
if (!m_ses.m_queued_for_checking.empty()) if (!m_ses.m_queued_for_checking.empty())
{ {
// if there are torrents waiting to be checked // if there are torrents waiting to be checked
@ -6609,6 +6610,7 @@ namespace libtorrent
TORRENT_ASSERT(found >= 1); TORRENT_ASSERT(found >= 1);
} }
} }
#endif
TORRENT_ASSERT(m_resume_entry.type() == lazy_entry::dict_t TORRENT_ASSERT(m_resume_entry.type() == lazy_entry::dict_t
|| m_resume_entry.type() == lazy_entry::none_t); || m_resume_entry.type() == lazy_entry::none_t);