From 537f21d1b9b5c0d302898bb16f64e13ab66a5136 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Sun, 16 Mar 2008 10:49:47 +0000 Subject: [PATCH] connection rate improvement when using a half-open connections limit --- include/libtorrent/connection_queue.hpp | 13 +++++++--- src/connection_queue.cpp | 32 +++++++++++++++++++------ src/peer_connection.cpp | 8 ++++++- src/session_impl.cpp | 6 +++-- src/torrent.cpp | 1 - 5 files changed, 46 insertions(+), 14 deletions(-) diff --git a/include/libtorrent/connection_queue.hpp b/include/libtorrent/connection_queue.hpp index 83930a4f2..c0e229a40 100644 --- a/include/libtorrent/connection_queue.hpp +++ b/include/libtorrent/connection_queue.hpp @@ -40,6 +40,10 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/socket.hpp" #include "libtorrent/time.hpp" +#ifdef TORRENT_CONNECTION_LOGGING +#include +#endif + namespace libtorrent { @@ -48,7 +52,9 @@ class connection_queue : public boost::noncopyable public: connection_queue(io_service& ios); - bool free_slots() const; + // if there are no free slots, returns the negative + // number of queued up connections + int free_slots() const; void enqueue(boost::function const& on_connect , boost::function const& on_timeout @@ -59,9 +65,7 @@ public: void close(); #ifndef NDEBUG - void check_invariant() const; - #endif private: @@ -98,6 +102,9 @@ private: #ifndef NDEBUG bool m_in_timeout_function; #endif +#ifdef TORRENT_CONNECTION_LOGGING + std::ofstream m_log; +#endif }; } diff --git a/src/connection_queue.cpp b/src/connection_queue.cpp index 3dfaa2a88..c54d723b5 100644 --- a/src/connection_queue.cpp +++ b/src/connection_queue.cpp @@ -45,10 +45,18 @@ namespace libtorrent #ifndef NDEBUG , m_in_timeout_function(false) #endif - {} + { +#ifdef TORRENT_CONNECTION_LOGGING + m_log.open("connection_queue.log"); +#endif + } - bool connection_queue::free_slots() const - { return m_num_connecting < m_half_open_limit || m_half_open_limit <= 0; } + int connection_queue::free_slots() const + { + mutex_t::scoped_lock l(m_mutex); + return m_half_open_limit == 0 ? std::numeric_limits::max() + : m_half_open_limit - m_queue.size(); + } void connection_queue::enqueue(boost::function const& on_connect , boost::function const& on_timeout @@ -109,7 +117,10 @@ namespace libtorrent } void connection_queue::limit(int limit) - { m_half_open_limit = limit; } + { + TORRENT_ASSERT(limit >= 0); + m_half_open_limit = limit; + } int connection_queue::limit() const { return m_half_open_limit; } @@ -133,8 +144,11 @@ namespace libtorrent { INVARIANT_CHECK; - if (!free_slots()) - return; +#ifdef TORRENT_CONNECTION_LOGGING + m_log << log_time() << " " << free_slots() << std::endl; +#endif + + if (m_num_connecting >= m_half_open_limit) return; if (m_queue.empty()) { @@ -171,7 +185,11 @@ namespace libtorrent } catch (std::exception&) {} #endif - if (!free_slots()) break; +#ifdef TORRENT_CONNECTION_LOGGING + m_log << log_time() << " " << free_slots() << std::endl; +#endif + + if (m_num_connecting >= m_half_open_limit) break; i = std::find_if(i, m_queue.end(), boost::bind(&entry::connecting, _1) == false); } } diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index 49b770d88..35fe73888 100755 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -2943,10 +2943,16 @@ namespace libtorrent m_connection_ticket = ticket; boost::shared_ptr t = m_torrent.lock(); - TORRENT_ASSERT(t); m_queued = false; TORRENT_ASSERT(m_connecting); + + if (!t) + { + disconnect("torrent aborted"); + return; + } + m_socket->open(t->get_interface().protocol(), ec); if (ec) { diff --git a/src/session_impl.cpp b/src/session_impl.cpp index 653ae4ab4..8afd870e6 100755 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -844,8 +844,9 @@ namespace aux { // round robin fashion, so that every torrent is // equallt likely to connect to a peer + int free_slots = m_half_open.free_slots(); if (!m_torrents.empty() - && m_half_open.free_slots() + && free_slots > -m_half_open.limit() && num_connections() < m_max_connections) { // this is the maximum number of connections we will @@ -869,6 +870,7 @@ namespace aux { if (t.try_connect_peer()) { --max_connections; + --free_slots; steps_since_last_connect = 0; } } @@ -894,7 +896,7 @@ namespace aux { // handing out a single connection, break if (steps_since_last_connect > num_torrents) break; // if there are no more free connection slots, abort - if (m_half_open.free_slots() == 0) break; + if (free_slots <= -m_half_open.limit()) break; // if we should not make any more connections // attempts this tick, abort if (max_connections == 0) break; diff --git a/src/torrent.cpp b/src/torrent.cpp index 91bb1bfb4..05584a41c 100755 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -2469,7 +2469,6 @@ namespace libtorrent bool torrent::want_more_peers() const { return int(m_connections.size()) < m_max_connections - && m_ses.m_half_open.free_slots() && !m_paused && m_state != torrent_status::checking_files && m_state != torrent_status::queued_for_checking;