From 476a72b0e479e74cb0c515653d7f1a1689daa3f8 Mon Sep 17 00:00:00 2001 From: Marcos Pinto Date: Thu, 16 Aug 2007 21:06:27 +0000 Subject: [PATCH] 1456 libtorrent sync --- libtorrent/include/libtorrent/alert_types.hpp | 11 + .../include/libtorrent/allocate_resources.hpp | 78 ------ .../include/libtorrent/bt_peer_connection.hpp | 1 - .../include/libtorrent/peer_connection.hpp | 3 +- libtorrent/include/libtorrent/policy.hpp | 29 +-- libtorrent/include/libtorrent/session.hpp | 7 - .../include/libtorrent/session_settings.hpp | 7 +- libtorrent/include/libtorrent/torrent.hpp | 24 +- .../libtorrent/web_peer_connection.hpp | 1 - libtorrent/src/allocate_resources.cpp | 225 ----------------- libtorrent/src/peer_connection.cpp | 85 ++----- libtorrent/src/policy.cpp | 86 ++++--- libtorrent/src/session.cpp | 1 - libtorrent/src/session_impl.cpp | 231 +++++++++++++----- libtorrent/src/torrent.cpp | 93 ++++--- 15 files changed, 341 insertions(+), 541 deletions(-) delete mode 100644 libtorrent/include/libtorrent/allocate_resources.hpp delete mode 100644 libtorrent/src/allocate_resources.cpp diff --git a/libtorrent/include/libtorrent/alert_types.hpp b/libtorrent/include/libtorrent/alert_types.hpp index 48491bca4..e6ade9a26 100755 --- a/libtorrent/include/libtorrent/alert_types.hpp +++ b/libtorrent/include/libtorrent/alert_types.hpp @@ -261,6 +261,17 @@ namespace libtorrent { return std::auto_ptr(new torrent_paused_alert(*this)); } }; + struct TORRENT_EXPORT torrent_checked_alert: torrent_alert + { + torrent_checked_alert(torrent_handle const& h, std::string const& msg) + : torrent_alert(h, alert::info, msg) + {} + + virtual std::auto_ptr clone() const + { return std::auto_ptr(new torrent_checked_alert(*this)); } + }; + + struct TORRENT_EXPORT url_seed_alert: torrent_alert { url_seed_alert( diff --git a/libtorrent/include/libtorrent/allocate_resources.hpp b/libtorrent/include/libtorrent/allocate_resources.hpp deleted file mode 100644 index 3d8237914..000000000 --- a/libtorrent/include/libtorrent/allocate_resources.hpp +++ /dev/null @@ -1,78 +0,0 @@ -/* - -Copyright (c) 2003, Magnus Jonsson -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - * Neither the name of the author nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ - -#ifndef TORRENT_ALLOCATE_RESOURCES_HPP_INCLUDED -#define TORRENT_ALLOCATE_RESOURCES_HPP_INCLUDED - -#include -#include - -#include - -#include "libtorrent/resource_request.hpp" -#include "libtorrent/peer_id.hpp" -#include "libtorrent/socket.hpp" -#include "libtorrent/session.hpp" - -namespace libtorrent -{ - class peer_connection; - class torrent; - - int saturated_add(int a, int b); - - // Function to allocate a limited resource fairly among many consumers. - // It takes into account the current use, and the consumer's desired use. - // Should be invoked periodically to allow it adjust to the situation (make - // sure "used" is updated between calls!). - // If resources = std::numeric_limits::max() it means there is an infinite - // supply of resources (so everyone can get what they want). - - void allocate_resources( - int resources - , std::map >& torrents - , resource_request torrent::* res); - - void allocate_resources( - int resources - , std::map& connections - , resource_request peer_connection::* res); - - // Used for global limits. - void allocate_resources( - int resources - , std::vector& _sessions - , resource_request session::* res); -} - - -#endif diff --git a/libtorrent/include/libtorrent/bt_peer_connection.hpp b/libtorrent/include/libtorrent/bt_peer_connection.hpp index 4f13b2fcf..0fcba89a8 100755 --- a/libtorrent/include/libtorrent/bt_peer_connection.hpp +++ b/libtorrent/include/libtorrent/bt_peer_connection.hpp @@ -65,7 +65,6 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/alert.hpp" #include "libtorrent/torrent_handle.hpp" #include "libtorrent/torrent.hpp" -#include "libtorrent/allocate_resources.hpp" #include "libtorrent/peer_request.hpp" #include "libtorrent/piece_block_progress.hpp" #include "libtorrent/config.hpp" diff --git a/libtorrent/include/libtorrent/peer_connection.hpp b/libtorrent/include/libtorrent/peer_connection.hpp index 976e03794..8dfc2b805 100755 --- a/libtorrent/include/libtorrent/peer_connection.hpp +++ b/libtorrent/include/libtorrent/peer_connection.hpp @@ -64,7 +64,6 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/alert.hpp" #include "libtorrent/torrent_handle.hpp" #include "libtorrent/torrent.hpp" -#include "libtorrent/allocate_resources.hpp" #include "libtorrent/peer_request.hpp" #include "libtorrent/piece_block_progress.hpp" #include "libtorrent/config.hpp" @@ -213,7 +212,7 @@ namespace libtorrent void add_stat(size_type downloaded, size_type uploaded); // is called once every second by the main loop - void second_tick(float tick_interval); + void second_tick(float tick_interval) throw(); boost::shared_ptr get_socket() const { return m_socket; } tcp::endpoint const& remote() const { return m_remote; } diff --git a/libtorrent/include/libtorrent/policy.hpp b/libtorrent/include/libtorrent/policy.hpp index 6c976d047..3f192ff51 100755 --- a/libtorrent/include/libtorrent/policy.hpp +++ b/libtorrent/include/libtorrent/policy.hpp @@ -155,6 +155,13 @@ namespace libtorrent // this is true if the peer is a seed bool seed; + // true if this peer currently is unchoked + // because of an optimistic unchoke. + // when the optimistic unchoke is moved to + // another peer, this peer will be choked + // if this is true + bool optimistically_unchoked; + // the time when this peer was optimistically unchoked // the last time. libtorrent::ptime last_optimistically_unchoked; @@ -203,25 +210,18 @@ namespace libtorrent peer_connection* connection; }; - int num_peers() const - { - return m_peers.size(); - } + int num_peers() const { return m_peers.size(); } - int num_uploads() const - { - return m_num_unchoked; - } - typedef std::list::iterator iterator; typedef std::list::const_iterator const_iterator; iterator begin_peer() { return m_peers.begin(); } iterator end_peer() { return m_peers.end(); } bool connect_one_peer(); + bool disconnect_one_peer(); private: - +/* bool unchoke_one_peer(); void choke_one_peer(); iterator find_choke_candidate(); @@ -233,8 +233,7 @@ namespace libtorrent void seed_choke_one_peer(); iterator find_seed_choke_candidate(); iterator find_seed_unchoke_candidate(); - - bool disconnect_one_peer(); +*/ iterator find_disconnect_candidate(); iterator find_connect_candidate(); @@ -242,10 +241,6 @@ namespace libtorrent torrent* m_torrent; - // the number of unchoked peers - // at any given time - int m_num_unchoked; - // free download we have got that hasn't // been distributed yet. size_type m_available_free_upload; @@ -253,7 +248,7 @@ namespace libtorrent // if there is a connection limit, // we disconnect one peer every minute in hope of // establishing a connection with a better peer - ptime m_last_optimistic_disconnect; +// ptime m_last_optimistic_disconnect; }; } diff --git a/libtorrent/include/libtorrent/session.hpp b/libtorrent/include/libtorrent/session.hpp index f721b3293..a123314ed 100755 --- a/libtorrent/include/libtorrent/session.hpp +++ b/libtorrent/include/libtorrent/session.hpp @@ -61,7 +61,6 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/version.hpp" #include "libtorrent/fingerprint.hpp" -#include "libtorrent/resource_request.hpp" #include "libtorrent/storage.hpp" #ifdef _MSC_VER @@ -266,12 +265,6 @@ namespace libtorrent void stop_natpmp(); void stop_upnp(); - // Resource management used for global limits. - resource_request m_ul_bandwidth_quota; - resource_request m_dl_bandwidth_quota; - resource_request m_uploads_quota; - resource_request m_connections_quota; - private: // just a way to initialize boost.filesystem diff --git a/libtorrent/include/libtorrent/session_settings.hpp b/libtorrent/include/libtorrent/session_settings.hpp index e5bb9879a..3a145c687 100644 --- a/libtorrent/include/libtorrent/session_settings.hpp +++ b/libtorrent/include/libtorrent/session_settings.hpp @@ -105,7 +105,8 @@ namespace libtorrent , send_redundant_have(false) , lazy_bitfields(true) , inactivity_timeout(600) - , unchoke_interval(20) + , unchoke_interval(15) + , optimistic_unchoke_multiplier(4) , num_want(200) , initial_picker_threshold(4) , allowed_fast_set_size(10) @@ -242,6 +243,10 @@ namespace libtorrent // the number of seconds between chokes/unchokes int unchoke_interval; + // the number of unchoke intervals between + // optimistic unchokes + int optimistic_unchoke_multiplier; + // if this is set, this IP will be reported do the // tracker in the ip= parameter. address announce_ip; diff --git a/libtorrent/include/libtorrent/torrent.hpp b/libtorrent/include/libtorrent/torrent.hpp index 2eef2656b..78bc53ab4 100755 --- a/libtorrent/include/libtorrent/torrent.hpp +++ b/libtorrent/include/libtorrent/torrent.hpp @@ -62,7 +62,6 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/tracker_manager.hpp" #include "libtorrent/stat.hpp" #include "libtorrent/alert.hpp" -#include "libtorrent/resource_request.hpp" #include "libtorrent/piece_picker.hpp" #include "libtorrent/config.hpp" #include "libtorrent/escape_string.hpp" @@ -154,10 +153,6 @@ namespace libtorrent bool verify_resume_data(entry& rd, std::string& error) { assert(m_storage); return m_storage->verify_resume_data(rd, error); } - // is called every second by session. This will - // caclulate the upload/download and number - // of connections this torrent needs. And prepare - // it for being used by allocate_resources. void second_tick(stat& accumulator, float tick_interval); // debug purpose only @@ -516,11 +511,6 @@ namespace libtorrent // -------------------------------------------- // RESOURCE MANAGEMENT - void distribute_resources(float tick_interval); - - resource_request m_uploads_quota; - resource_request m_connections_quota; - void set_peer_upload_limit(tcp::endpoint ip, int limit); void set_peer_download_limit(tcp::endpoint ip, int limit); @@ -530,7 +520,9 @@ namespace libtorrent int download_limit() const; void set_max_uploads(int limit); + int max_uploads() const { return m_max_uploads; } void set_max_connections(int limit); + int max_connections() const { return m_max_connections; } void move_storage(fs::path const& save_path); // unless this returns true, new connections must wait @@ -705,9 +697,9 @@ namespace libtorrent // determine the timeout until next try. int m_failed_trackers; - // this is a counter that is increased every - // second, and when it reaches 10, the policy::pulse() - // is called and the time scaler is reset to 0. + // this is a counter that is decreased every + // second, and when it reaches 0, the policy::pulse() + // is called and the time scaler is reset to 10. int m_time_scaler; // the bitmask that says which pieces we have @@ -774,6 +766,12 @@ namespace libtorrent session_settings const& m_settings; storage_constructor_type m_storage_constructor; + + // the maximum number of uploads for this torrent + int m_max_uploads; + + // the maximum number of connections for this torrent + int m_max_connections; #ifndef TORRENT_DISABLE_EXTENSIONS typedef std::list > extension_list_t; diff --git a/libtorrent/include/libtorrent/web_peer_connection.hpp b/libtorrent/include/libtorrent/web_peer_connection.hpp index b3ca73c4d..1290f14a1 100755 --- a/libtorrent/include/libtorrent/web_peer_connection.hpp +++ b/libtorrent/include/libtorrent/web_peer_connection.hpp @@ -65,7 +65,6 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/alert.hpp" #include "libtorrent/torrent_handle.hpp" #include "libtorrent/torrent.hpp" -#include "libtorrent/allocate_resources.hpp" #include "libtorrent/peer_request.hpp" #include "libtorrent/piece_block_progress.hpp" #include "libtorrent/config.hpp" diff --git a/libtorrent/src/allocate_resources.cpp b/libtorrent/src/allocate_resources.cpp deleted file mode 100644 index deef06dc4..000000000 --- a/libtorrent/src/allocate_resources.cpp +++ /dev/null @@ -1,225 +0,0 @@ -/* - -Copyright (c) 2006, Magnus Jonsson, Arvid Norberg -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - * Neither the name of the author nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ - -//The Standard Library defines the two template functions std::min() -//and std::max() in the header. In general, you should -//use these template functions for calculating the min and max values -//of a pair. Unfortunately, Visual C++ does not define these function -// templates. This is because the names min and max clash with -//the traditional min and max macros defined in . -//As a workaround, Visual C++ defines two alternative templates with -//identical functionality called _cpp_min() and _cpp_max(). You can -//use them instead of std::min() and std::max().To disable the -//generation of the min and max macros in Visual C++, #define -//NOMINMAX before #including . - -#include "libtorrent/pch.hpp" - -#ifdef _WIN32 - //support boost1.32.0(2004-11-19 18:47) - //now all libs can be compiled and linked with static module - #define NOMINMAX -#endif - -#include "libtorrent/allocate_resources.hpp" -#include "libtorrent/size_type.hpp" -#include "libtorrent/peer_connection.hpp" -#include "libtorrent/torrent.hpp" -#include "libtorrent/aux_/allocate_resources_impl.hpp" - -#include -#include -#include - -#if defined(_MSC_VER) && _MSC_VER < 1310 -#define for if (false) {} else for -#else -#include -#endif - -namespace libtorrent -{ - int saturated_add(int a, int b) - { - assert(a >= 0); - assert(b >= 0); - assert(a <= resource_request::inf); - assert(b <= resource_request::inf); - assert(resource_request::inf + resource_request::inf < 0); - - unsigned int sum = unsigned(a) + unsigned(b); - if (sum > unsigned(resource_request::inf)) - sum = resource_request::inf; - - assert(sum >= unsigned(a) && sum >= unsigned(b)); - return int(sum); - } - -#if defined(_MSC_VER) && _MSC_VER < 1310 - - namespace detail - { - struct iterator_wrapper - { - typedef std::map >::iterator orig_iter; - - orig_iter iter; - - iterator_wrapper(orig_iter i): iter(i) {} - void operator++() { ++iter; } - torrent& operator*() { return *(iter->second); } - bool operator==(const iterator_wrapper& i) const - { return iter == i.iter; } - bool operator!=(const iterator_wrapper& i) const - { return iter != i.iter; } - }; - - struct iterator_wrapper2 - { - typedef std::map::iterator orig_iter; - - orig_iter iter; - - iterator_wrapper2(orig_iter i): iter(i) {} - void operator++() { ++iter; } - peer_connection& operator*() { return *(iter->second); } - bool operator==(const iterator_wrapper2& i) const - { return iter == i.iter; } - bool operator!=(const iterator_wrapper2& i) const - { return iter != i.iter; } - }; - - } - - void allocate_resources( - int resources - , std::map >& c - , resource_request torrent::* res) - { - aux::allocate_resources_impl( - resources - , detail::iterator_wrapper(c.begin()) - , detail::iterator_wrapper(c.end()) - , res); - } - - void allocate_resources( - int resources - , std::map& c - , resource_request peer_connection::* res) - { - aux::allocate_resources_impl( - resources - , detail::iterator_wrapper2(c.begin()) - , detail::iterator_wrapper2(c.end()) - , res); - } - -#else - - namespace aux - { - peer_connection& pick_peer( - std::pair - , boost::intrusive_ptr > const& p) - { - return *p.second; - } - - peer_connection& pick_peer2( - std::pair const& p) - { - return *p.second; - } - - torrent& deref(std::pair > const& p) - { - return *p.second; - } - - session& deref(session* p) - { - return *p; - } - } - - void allocate_resources( - int resources - , std::map >& c - , resource_request torrent::* res) - { - typedef std::map >::iterator orig_iter; - typedef std::pair > in_param; - typedef boost::transform_iterator new_iter; - - aux::allocate_resources_impl( - resources - , new_iter(c.begin(), &aux::deref) - , new_iter(c.end(), &aux::deref) - , res); - } - - void allocate_resources( - int resources - , std::map& c - , resource_request peer_connection::* res) - { - typedef std::map::iterator orig_iter; - typedef std::pair in_param; - typedef boost::transform_iterator new_iter; - - aux::allocate_resources_impl( - resources - , new_iter(c.begin(), &aux::pick_peer2) - , new_iter(c.end(), &aux::pick_peer2) - , res); - } - - void allocate_resources( - int resources - , std::vector& _sessions - , resource_request session::* res) - { - typedef std::vector::iterator orig_iter; - typedef session* in_param; - typedef boost::transform_iterator new_iter; - - aux::allocate_resources_impl( - resources - , new_iter(_sessions.begin(), &aux::deref) - , new_iter(_sessions.end(), &aux::deref) - , res); - } - -#endif - -} // namespace libtorrent diff --git a/libtorrent/src/peer_connection.cpp b/libtorrent/src/peer_connection.cpp index 86d4e1500..2be76e5dd 100755 --- a/libtorrent/src/peer_connection.cpp +++ b/libtorrent/src/peer_connection.cpp @@ -109,8 +109,8 @@ namespace libtorrent , m_prefer_whole_pieces(false) , m_request_large_blocks(false) , m_non_prioritized(false) - , m_upload_limit(resource_request::inf) - , m_download_limit(resource_request::inf) + , m_upload_limit(bandwidth_limit::inf) + , m_download_limit(bandwidth_limit::inf) , m_peer_info(peerinfo) , m_speed(slow) , m_connection_ticket(-1) @@ -185,8 +185,8 @@ namespace libtorrent , m_prefer_whole_pieces(false) , m_request_large_blocks(false) , m_non_prioritized(false) - , m_upload_limit(resource_request::inf) - , m_download_limit(resource_request::inf) + , m_upload_limit(bandwidth_limit::inf) + , m_download_limit(bandwidth_limit::inf) , m_peer_info(peerinfo) , m_speed(slow) , m_remote_bytes_dled(0) @@ -526,30 +526,18 @@ namespace libtorrent && p.start + p.length <= t->torrent_file().piece_size(p.piece) && (p.start % t->block_size() == 0); } - - struct disconnect_torrent - { - disconnect_torrent(boost::weak_ptr& t): m_t(&t) {} - ~disconnect_torrent() { if (m_t) m_t->reset(); } - void cancel() { m_t = 0; } - private: - boost::weak_ptr* m_t; - }; - + void peer_connection::attach_to_torrent(sha1_hash const& ih) { INVARIANT_CHECK; assert(!m_disconnecting); - m_torrent = m_ses.find_torrent(ih); - + assert(m_torrent.expired()); + boost::weak_ptr wpt = m_ses.find_torrent(ih); boost::shared_ptr t = m_torrent.lock(); if (t && t->is_aborted()) - { - m_torrent.reset(); t.reset(); - } if (!t) { @@ -560,7 +548,6 @@ namespace libtorrent throw std::runtime_error("got info-hash that is not in our session"); } - disconnect_torrent disconnect(m_torrent); if (t->is_paused()) { // paused torrents will not accept @@ -571,21 +558,27 @@ namespace libtorrent throw std::runtime_error("connection rejected by paused torrent"); } + assert(m_torrent.expired()); // check to make sure we don't have another connection with the same // info_hash and peer_id. If we do. close this connection. t->attach_peer(this); + m_torrent = wpt; + + assert(!m_torrent.expired()); // if the torrent isn't ready to accept // connections yet, we'll have to wait with // our initialization if (t->ready_for_connections()) init(); + assert(!m_torrent.expired()); + // assume the other end has no pieces // if we don't have valid metadata yet, // leave the vector unallocated assert(m_num_pieces == 0); std::fill(m_have_piece.begin(), m_have_piece.end(), false); - disconnect.cancel(); + assert(!m_torrent.expired()); } // message handlers @@ -1543,7 +1536,7 @@ namespace libtorrent // if the peer has the piece and we want // to download it, request it - if (m_have_piece.size() > index + if (int(m_have_piece.size()) > index && m_have_piece[index] && t->has_picker() && t->picker().piece_priority(index) > 0) @@ -1900,7 +1893,7 @@ namespace libtorrent void peer_connection::set_upload_limit(int limit) { assert(limit >= -1); - if (limit == -1) limit = resource_request::inf; + if (limit == -1) limit = std::numeric_limits::max(); if (limit < 10) limit = 10; m_upload_limit = limit; m_bandwidth_limit[upload_channel].throttle(m_upload_limit); @@ -1909,7 +1902,7 @@ namespace libtorrent void peer_connection::set_download_limit(int limit) { assert(limit >= -1); - if (limit == -1) limit = resource_request::inf; + if (limit == -1) limit = std::numeric_limits::max(); if (limit < 10) limit = 10; m_download_limit = limit; m_bandwidth_limit[download_channel].throttle(m_download_limit); @@ -2044,10 +2037,13 @@ namespace libtorrent if (m_packet_size >= m_recv_pos) m_recv_buffer.resize(m_packet_size); } - void peer_connection::second_tick(float tick_interval) + void peer_connection::second_tick(float tick_interval) throw() { INVARIANT_CHECK; + try + { + ptime now(time_now()); boost::shared_ptr t = m_torrent.lock(); @@ -2186,43 +2182,14 @@ namespace libtorrent } fill_send_buffer(); -/* - size_type diff = share_diff(); - - enum { block_limit = 2 }; // how many blocks difference is considered unfair - - // if the peer has been choked, send the current piece - // as fast as possible - if (diff > block_limit*m_torrent->block_size() || m_torrent->is_seed() || is_choked()) - { - // if we have downloaded more than one piece more - // than we have uploaded OR if we are a seed - // have an unlimited upload rate - m_ul_bandwidth_quota.wanted = std::numeric_limits::max(); } - else + catch (std::exception& e) { - float ratio = m_torrent->ratio(); - // if we have downloaded too much, response with an - // upload rate of 10 kB/s more than we dowlload - // if we have uploaded too much, send with a rate of - // 10 kB/s less than we receive - int bias = 0; - if (diff > -block_limit*m_torrent->block_size()) - { - bias = static_cast(m_statistics.download_rate() * ratio) / 2; - if (bias < 10*1024) bias = 10*1024; - } - else - { - bias = -static_cast(m_statistics.download_rate() * ratio) / 2; - } - m_ul_bandwidth_quota.wanted = static_cast(m_statistics.download_rate()) + bias; - - // the maximum send_quota given our download rate from this peer - if (m_ul_bandwidth_quota.wanted < 256) m_ul_bandwidth_quota.wanted = 256; +#ifdef TORRENT_VERBOSE_LOGGING + (*m_logger) << "**ERROR**: " << e.what() << "\n"; +#endif + m_ses.connection_failed(m_socket, remote(), e.what()); } -*/ } void peer_connection::fill_send_buffer() diff --git a/libtorrent/src/policy.cpp b/libtorrent/src/policy.cpp index e5d625dff..129f10a3b 100755 --- a/libtorrent/src/policy.cpp +++ b/libtorrent/src/policy.cpp @@ -189,7 +189,8 @@ namespace libtorrent // infinite loop, fighting to request the same blocks. void request_a_block(torrent& t, peer_connection& c) { - assert(!t.is_seed()); + if (t.is_seed()) return; + assert(t.valid_metadata()); assert(c.peer_info_struct() != 0 || !dynamic_cast(&c)); int num_requests = c.desired_queue_size() @@ -331,9 +332,8 @@ namespace libtorrent policy::policy(torrent* t) : m_torrent(t) - , m_num_unchoked(0) , m_available_free_upload(0) - , m_last_optimistic_disconnect(min_time()) +// , m_last_optimistic_disconnect(min_time()) { assert(t); } // disconnects and removes all peers that are now filtered @@ -375,7 +375,7 @@ namespace libtorrent m_peers.erase(i++); } } - +/* // finds the peer that has the worst download rate // and returns it. May return 0 if all peers are // choked. @@ -457,7 +457,7 @@ namespace libtorrent } return unchoke_peer; } - +*/ policy::iterator policy::find_disconnect_candidate() { INVARIANT_CHECK; @@ -542,7 +542,7 @@ namespace libtorrent return candidate; } - +/* policy::iterator policy::find_seed_choke_candidate() { INVARIANT_CHECK; @@ -648,7 +648,7 @@ namespace libtorrent --m_num_unchoked; } } - +*/ void policy::pulse() { INVARIANT_CHECK; @@ -680,7 +680,7 @@ namespace libtorrent // ------------------------------------- // maintain the number of connections // ------------------------------------- - +/* // count the number of connected peers except for peers // that are currently in the process of disconnecting int num_connected_peers = 0; @@ -692,10 +692,9 @@ namespace libtorrent ++num_connected_peers; } - if (m_torrent->m_connections_quota.given != std::numeric_limits::max()) + if (m_torrent->max_connections() != std::numeric_limits::max()) { - - int max_connections = m_torrent->m_connections_quota.given; + int max_connections = m_torrent->max_connections(); if (num_connected_peers >= max_connections) { @@ -723,7 +722,7 @@ namespace libtorrent --num_connected_peers; } } - +*/ // ------------------------ // upload shift // ------------------------ @@ -754,7 +753,7 @@ namespace libtorrent , m_torrent->end() , m_available_free_upload); } - +/* // ------------------------ // seed choking policy // ------------------------ @@ -870,6 +869,7 @@ namespace libtorrent while (m_num_unchoked < m_torrent->m_uploads_quota.given && unchoke_one_peer()); } +*/ } int policy::count_choked() const @@ -902,7 +902,8 @@ namespace libtorrent // override at a time assert(c.remote() == c.get_socket()->remote_endpoint()); - if (m_torrent->num_peers() >= m_torrent->m_connections_quota.given + if (m_torrent->num_peers() >= m_torrent->max_connections() + && m_torrent->session().num_connections() >= m_torrent->session().max_connections() && c.remote().address() != m_torrent->current_tracker().address()) { throw protocol_error("too many connections, refusing incoming connection"); // cause a disconnect @@ -984,7 +985,7 @@ namespace libtorrent i->connection = &c; assert(i->connection); i->connected = time_now(); - m_last_optimistic_disconnect = time_now(); +// m_last_optimistic_disconnect = time_now(); } void policy::peer_from_tracker(const tcp::endpoint& remote, const peer_id& pid @@ -1172,14 +1173,38 @@ namespace libtorrent // In that case we don't care if people are leeching, they // can't pay for their downloads anyway. if (c.is_choked() - && m_num_unchoked < m_torrent->m_uploads_quota.given + && m_torrent->session().num_uploads() < m_torrent->session().max_uploads() && (m_torrent->ratio() == 0 || c.share_diff() >= -free_upload_amount || m_torrent->is_seed())) { - c.send_unchoke(); - ++m_num_unchoked; + m_torrent->session().unchoke_peer(c); } +#if defined(TORRENT_VERBOSE_LOGGING) + else if (c.is_choked()) + { + std::string reason; + if (m_torrent->session().num_uploads() >= m_torrent->session().max_uploads()) + { + reason = "the number of uploads (" + + boost::lexical_cast(m_torrent->session().num_uploads()) + + ") is more than or equal to the limit (" + + boost::lexical_cast(m_torrent->session().max_uploads()) + + ")"; + } + else + { + reason = "the share ratio (" + + boost::lexical_cast(c.share_diff()) + + ") is <= free_upload_amount (" + + boost::lexical_cast(int(free_upload_amount)) + + ") and we are not seeding and the ratio (" + + boost::lexical_cast(m_torrent->ratio()) + + ")is non-zero"; + } + (*c.m_logger) << time_now_string() << " DID NOT UNCHOKE [ " << reason << " ]\n"; + } +#endif } // called when a peer is no longer interested in us @@ -1211,7 +1236,7 @@ namespace libtorrent } */ } - +/* bool policy::unchoke_one_peer() { INVARIANT_CHECK; @@ -1240,7 +1265,7 @@ namespace libtorrent p->connection->send_choke(); --m_num_unchoked; } - +*/ bool policy::connect_one_peer() { INVARIANT_CHECK; @@ -1256,7 +1281,7 @@ namespace libtorrent try { - p->connected = m_last_optimistic_disconnect = time_now(); + p->connected = time_now(); p->connection = m_torrent->connect_to_peer(&*p); if (p->connection == 0) return false; p->connection->add_stat(p->prev_amount_download, p->prev_amount_upload); @@ -1296,6 +1321,7 @@ namespace libtorrent // assert(c.is_disconnecting()); bool unchoked = false; +#warning extract policy::peer pointer from c iterator i = std::find_if( m_peers.begin() , m_peers.end() @@ -1305,6 +1331,7 @@ namespace libtorrent if (i == m_peers.end()) return; assert(i->connection == &c); i->connection = 0; + i->optimistically_unchoked = false; i->connected = time_now(); if (!c.is_choked() && !m_torrent->is_aborted()) @@ -1330,15 +1357,15 @@ namespace libtorrent i->prev_amount_download += c.statistics().total_payload_download(); i->prev_amount_upload += c.statistics().total_payload_upload(); - if (unchoked) - { +// if (unchoked) +// { // if the peer that is diconnecting is unchoked // then unchoke another peer in order to maintain // the total number of unchoked peers - --m_num_unchoked; - if (m_torrent->is_seed()) seed_unchoke_one_peer(); - else unchoke_one_peer(); - } +// --m_num_unchoked; +// if (m_torrent->is_seed()) seed_unchoke_one_peer(); +// else unchoke_one_peer(); +// } } catch (std::exception& e) { @@ -1376,7 +1403,6 @@ namespace libtorrent void policy::check_invariant() const { if (m_torrent->is_aborted()) return; - int actual_unchoked = 0; int connected_peers = 0; int total_connections = 0; @@ -1405,10 +1431,7 @@ namespace libtorrent ++nonempty_connections; if (!p.connection->is_disconnecting()) ++connected_peers; - if (!p.connection->is_choked()) ++actual_unchoked; } -// assert(actual_unchoked <= m_torrent->m_uploads_quota.given); - assert(actual_unchoked == m_num_unchoked); int num_torrent_peers = 0; for (torrent::const_peer_iterator i = m_torrent->begin(); @@ -1475,6 +1498,7 @@ namespace libtorrent , failcount(0) , hashfails(0) , seed(false) + , optimistically_unchoked(false) , last_optimistically_unchoked(min_time()) , connected(min_time()) , trust_points(0) diff --git a/libtorrent/src/session.cpp b/libtorrent/src/session.cpp index 485c90d62..6d6fa55b2 100755 --- a/libtorrent/src/session.cpp +++ b/libtorrent/src/session.cpp @@ -68,7 +68,6 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/alert_types.hpp" #include "libtorrent/invariant_check.hpp" #include "libtorrent/file.hpp" -#include "libtorrent/allocate_resources.hpp" #include "libtorrent/bt_peer_connection.hpp" #include "libtorrent/ip_filter.hpp" #include "libtorrent/socket.hpp" diff --git a/libtorrent/src/session_impl.cpp b/libtorrent/src/session_impl.cpp index 81f48a3ce..694e5f49d 100755 --- a/libtorrent/src/session_impl.cpp +++ b/libtorrent/src/session_impl.cpp @@ -68,7 +68,6 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/alert_types.hpp" #include "libtorrent/invariant_check.hpp" #include "libtorrent/file.hpp" -#include "libtorrent/allocate_resources.hpp" #include "libtorrent/bt_peer_connection.hpp" #include "libtorrent/ip_filter.hpp" #include "libtorrent/socket.hpp" @@ -223,6 +222,12 @@ namespace detail if (!m_ses.is_aborted()) { m_ses.m_torrents.insert(std::make_pair(t->info_hash, t->torrent_ptr)); + if (m_ses.m_alerts.should_post(alert::info)) + { + m_ses.m_alerts.post_alert(torrent_checked_alert( + processing->torrent_ptr->get_handle() + , "torrent finished checking")); + } if (t->torrent_ptr->is_seed() && m_ses.m_alerts.should_post(alert::info)) { m_ses.m_alerts.post_alert(torrent_finished_alert( @@ -345,6 +350,12 @@ namespace detail processing->torrent_ptr->files_checked(processing->unfinished_pieces); m_ses.m_torrents.insert(std::make_pair( processing->info_hash, processing->torrent_ptr)); + if (m_ses.m_alerts.should_post(alert::info)) + { + m_ses.m_alerts.post_alert(torrent_checked_alert( + processing->torrent_ptr->get_handle() + , "torrent finished checking")); + } if (processing->torrent_ptr->is_seed() && m_ses.m_alerts.should_post(alert::info)) { @@ -505,8 +516,12 @@ namespace detail , m_listen_interface(address::from_string(listen_interface), listen_port_range.first) , m_external_listen_port(0) , m_abort(false) - , m_max_uploads(-1) - , m_max_connections(-1) + , m_max_uploads(8) + , m_max_connections(200) + , m_num_unchoked(0) + , m_unchoke_time_scaler(0) + , m_optimistic_unchoke_time_scaler(0) + , m_disconnect_time_scaler(0) , m_incoming_connection(false) , m_last_tick(time_now()) #ifndef TORRENT_DISABLE_DHT @@ -821,7 +836,10 @@ namespace detail assert(p->is_disconnecting()); connection_map::iterator i = m_connections.find(p->get_socket()); if (i != m_connections.end()) + { + if (!i->second->is_choked()) --m_num_unchoked; m_connections.erase(i); + } } void session_impl::set_peer_id(peer_id const& id) @@ -901,7 +919,9 @@ namespace detail // round robin fashion, so that every torrent is // equallt likely to connect to a peer - if (!m_torrents.empty() && m_half_open.free_slots()) + if (!m_torrents.empty() + && m_half_open.free_slots() + && num_connections() < m_max_connections) { // this is the maximum number of connections we will // attempt this tick @@ -918,11 +938,13 @@ namespace detail { torrent& t = *i->second; if (t.want_more_peers()) + { if (t.try_connect_peer()) { --max_connections; steps_since_last_connect = 0; } + } ++m_next_connect_torrent; ++steps_since_last_connect; ++i; @@ -976,18 +998,7 @@ namespace detail continue; } - try - { - c.keep_alive(); - } - catch (std::exception& exc) - { -#ifdef TORRENT_VERBOSE_LOGGING - (*c.m_logger) << "**ERROR**: " << exc.what() << "\n"; -#endif - c.set_failed(); - c.disconnect(); - } + c.keep_alive(); } // check each torrent for tracker updates @@ -1019,30 +1030,148 @@ namespace detail } m_stat.second_tick(tick_interval); - // distribute the maximum upload rate among the torrents - assert(m_max_uploads >= -1); - assert(m_max_connections >= -1); - - allocate_resources(m_max_uploads == -1 - ? std::numeric_limits::max() - : m_max_uploads - , m_torrents - , &torrent::m_uploads_quota); - - allocate_resources(m_max_connections == -1 - ? std::numeric_limits::max() - : m_max_connections - , m_torrents - , &torrent::m_connections_quota); - - for (std::map >::iterator i - = m_torrents.begin(); i != m_torrents.end(); ++i) + // -------------------------------------------------------------- + // unchoke set and optimistic unchoke calculations + // -------------------------------------------------------------- + m_unchoke_time_scaler--; + if (m_unchoke_time_scaler <= 0 && !m_connections.empty()) { -#ifndef NDEBUG - i->second->check_invariant(); -#endif - i->second->distribute_resources(tick_interval); + m_unchoke_time_scaler = settings().unchoke_interval; + + std::vector peers; + for (connection_map::iterator i = m_connections.begin() + , end(m_connections.end()); i != end; ++i) + { + peer_connection* p = i->second.get(); + torrent* t = p->associated_torrent().lock().get(); + if (!p->peer_info_struct() + || !p->is_peer_interested() + || p->is_disconnecting() + || p->is_connecting() + || (p->share_diff() < -free_upload_amount + && t && !t->is_seed())) + { + if (!i->second->is_choked()) + i->second->send_choke(); + continue; + } + peers.push_back(i->second.get()); + } + + // sort the peers that are eligible for unchoke by download rate and secondary + // by total upload. The reason for this is, if all torrents are being seeded, + // the download rate will be 0, and the peers we have sent the least to should + // be unchoked + std::sort(peers.begin(), peers.end() + , bind(&stat::total_payload_upload, bind(&peer_connection::statistics, _1)) + < bind(&stat::total_payload_upload, bind(&peer_connection::statistics, _2))); + + std::stable_sort(peers.begin(), peers.end() + , bind(&stat::download_payload_rate, bind(&peer_connection::statistics, _1)) + > bind(&stat::download_payload_rate, bind(&peer_connection::statistics, _2))); + + // reserve one upload slot for optimistic unchokes + int unchoke_set_size = m_max_uploads - 1; + + m_num_unchoked = 0; + // go through all the peers and unchoke the first ones and choke + // all the other ones. + for (std::vector::iterator i = peers.begin() + , end(peers.end()); i != end; ++i) + { + peer_connection* p = *i; + assert(p); + if (unchoke_set_size > 0) + { + if (p->is_choked()) p->send_unchoke(); + assert(p->peer_info_struct()); + if (p->peer_info_struct()->optimistically_unchoked) + { + // force a new optimistic unchoke + m_optimistic_unchoke_time_scaler = 0; + p->peer_info_struct()->optimistically_unchoked = false; + } + --unchoke_set_size; + ++m_num_unchoked; + } + else + { + if (!p->is_choked() && !p->peer_info_struct()->optimistically_unchoked) + p->send_choke(); + } + } + + m_optimistic_unchoke_time_scaler--; + if (m_optimistic_unchoke_time_scaler <= 0) + { + m_optimistic_unchoke_time_scaler + = settings().optimistic_unchoke_multiplier; + + // find the peer that has been waiting the longest to be optimistically + // unchoked + connection_map::iterator current_optimistic_unchoke = m_connections.end(); + connection_map::iterator optimistic_unchoke_candidate = m_connections.end(); + ptime last_unchoke = max_time(); + + for (connection_map::iterator i = m_connections.begin() + , end(m_connections.end()); i != end; ++i) + { + peer_connection* p = i->second.get(); + assert(p); + policy::peer* pi = p->peer_info_struct(); + if (!pi) continue; + if (pi->optimistically_unchoked) + { + assert(current_optimistic_unchoke == m_connections.end()); + current_optimistic_unchoke = i; + } + if (pi->last_optimistically_unchoked < last_unchoke + && !p->is_connecting() + && !p->is_disconnecting() + && p->is_peer_interested()) + { + last_unchoke = pi->last_optimistically_unchoked; + optimistic_unchoke_candidate = i; + } + } + + if (optimistic_unchoke_candidate != m_connections.end() + && optimistic_unchoke_candidate != current_optimistic_unchoke) + { + if (current_optimistic_unchoke != m_connections.end()) + { + current_optimistic_unchoke->second->send_choke(); + current_optimistic_unchoke->second->peer_info_struct()->optimistically_unchoked = false; + } + + optimistic_unchoke_candidate->second->send_unchoke(); + optimistic_unchoke_candidate->second->peer_info_struct()->optimistically_unchoked = true; + } + + if (optimistic_unchoke_candidate != m_connections.end()) + ++m_num_unchoked; + } + } + + // -------------------------------------------------------------- + // disconnect peers when we have too many + // -------------------------------------------------------------- + --m_disconnect_time_scaler; + if (m_disconnect_time_scaler <= 0) + { + m_disconnect_time_scaler = 60; + + // every 60 seconds, disconnect the worst peer + // if we have reached the connection limit + if (num_connections() >= max_connections() && !m_torrents.empty()) + { + torrent_map::iterator i = std::max_element(m_torrents.begin(), m_torrents.end() + , bind(&torrent::num_peers, bind(&torrent_map::value_type::second, _1))); + + assert(i != m_torrents.end()); + i->second->get_policy().disconnect_one_peer(); + } } } catch (std::exception& exc) @@ -1866,24 +1995,6 @@ namespace detail m_bandwidth_manager[peer_connection::upload_channel]->throttle(bytes_per_second); } - int session_impl::num_uploads() const - { - int uploads = 0; - mutex_t::scoped_lock l(m_mutex); - for (torrent_map::const_iterator i = m_torrents.begin() - , end(m_torrents.end()); i != end; i++) - { - uploads += i->second->get_policy().num_uploads(); - } - return uploads; - } - - int session_impl::num_connections() const - { - mutex_t::scoped_lock l(m_mutex); - return m_connections.size(); - } - std::auto_ptr session_impl::pop_alert() { mutex_t::scoped_lock l(m_mutex); @@ -1978,17 +2089,25 @@ namespace detail void session_impl::check_invariant(const char *place) { assert(place); + int unchokes = 0; + int num_optimistic = 0; for (connection_map::iterator i = m_connections.begin(); i != m_connections.end(); ++i) { assert(i->second); boost::shared_ptr t = i->second->associated_torrent().lock(); + if (!i->second->is_choked()) ++unchokes; + if (i->second->peer_info_struct() + && i->second->peer_info_struct()->optimistically_unchoked) + ++num_optimistic; if (t) { assert(t->get_policy().has_connection(boost::get_pointer(i->second))); } } + assert(num_optimistic == 0 || num_optimistic == 1); + assert(m_num_unchoked == unchokes); } #endif diff --git a/libtorrent/src/torrent.cpp b/libtorrent/src/torrent.cpp index 13309c1e7..f26563503 100755 --- a/libtorrent/src/torrent.cpp +++ b/libtorrent/src/torrent.cpp @@ -199,18 +199,12 @@ namespace libtorrent , m_connections_initialized(true) , m_settings(s) , m_storage_constructor(sc) + , m_max_uploads(std::numeric_limits::max()) + , m_max_connections(std::numeric_limits::max()) { #ifndef NDEBUG m_initial_done = 0; #endif - - m_uploads_quota.min = 0; - m_connections_quota.min = 2; - // this will be corrected the next time the main session - // distributes resources, i.e. on average in 0.5 seconds - m_connections_quota.given = 100; - m_uploads_quota.max = std::numeric_limits::max(); - m_connections_quota.max = std::numeric_limits::max(); m_policy.reset(new policy(this)); } @@ -277,13 +271,6 @@ namespace libtorrent if (name) m_name.reset(new std::string(name)); - m_uploads_quota.min = 0; - m_connections_quota.min = 2; - // this will be corrected the next time the main session - // distributes resources, i.e. on average in 0.5 seconds - m_connections_quota.given = 100; - m_uploads_quota.max = std::numeric_limits::max(); - m_connections_quota.max = std::numeric_limits::max(); if (tracker_url) { m_trackers.push_back(announce_entry(tracker_url)); @@ -329,6 +316,14 @@ namespace libtorrent INVARIANT_CHECK; +#if defined(TORRENT_VERBOSE_LOGGING) + for (peer_iterator i = m_connections.begin(); + i != m_connections.end(); ++i) + { + (*i->second->m_logger) << "*** DESTRUCTING TORRENT\n"; + } +#endif + assert(m_abort); if (!m_connections.empty()) disconnect_all(); @@ -1020,6 +1015,15 @@ namespace libtorrent m_event = tracker_request::stopped; // disconnect all peers and close all // files belonging to the torrents + +#if defined(TORRENT_VERBOSE_LOGGING) + for (peer_iterator i = m_connections.begin(); + i != m_connections.end(); ++i) + { + (*i->second->m_logger) << "*** ABORTING TORRENT\n"; + } +#endif + disconnect_all(); if (m_owning_storage.get()) m_storage->async_release_files(); m_owning_storage = 0; @@ -1890,7 +1894,7 @@ namespace libtorrent void torrent::attach_peer(peer_connection* p) { - INVARIANT_CHECK; +// INVARIANT_CHECK; assert(p != 0); assert(!p->is_local()); @@ -1955,7 +1959,7 @@ namespace libtorrent bool torrent::want_more_peers() const { - return int(m_connections.size()) < m_connections_quota.given + return int(m_connections.size()) < m_max_connections && m_ses.m_half_open.free_slots() && !m_paused; } @@ -2425,15 +2429,15 @@ namespace libtorrent void torrent::set_max_uploads(int limit) { assert(limit >= -1); - if (limit == -1) limit = std::numeric_limits::max(); - m_uploads_quota.max = std::max(m_uploads_quota.min, limit); + if (limit < 0) limit = std::numeric_limits::max(); + m_max_uploads = limit; } void torrent::set_max_connections(int limit) { assert(limit >= -1); - if (limit == -1) limit = std::numeric_limits::max(); - m_connections_quota.max = std::max(m_connections_quota.min, limit); + if (limit < -1) limit = std::numeric_limits::max(); + m_max_connections = limit; } void torrent::set_peer_upload_limit(tcp::endpoint ip, int limit) @@ -2496,6 +2500,14 @@ namespace libtorrent } #endif +#if defined(TORRENT_VERBOSE_LOGGING) + for (peer_iterator i = m_connections.begin(); + i != m_connections.end(); ++i) + { + (*i->second->m_logger) << "*** PAUSING TORRENT\n"; + } +#endif + disconnect_all(); m_paused = true; // tell the tracker that we stopped @@ -2528,10 +2540,6 @@ namespace libtorrent #endif m_paused = false; - m_uploads_quota.min = 0; - m_connections_quota.min = 2; - m_uploads_quota.max = std::numeric_limits::max(); - m_connections_quota.max = std::numeric_limits::max(); // tell the tracker that we're back m_event = tracker_request::started; @@ -2545,10 +2553,6 @@ namespace libtorrent { INVARIANT_CHECK; - m_connections_quota.used = (int)m_connections.size(); - m_uploads_quota.used = m_policy->num_uploads(); - m_uploads_quota.max = (int)m_connections.size(); - #ifndef TORRENT_DISABLE_EXTENSIONS for (extension_list_t::iterator i = m_extensions.begin() , end(m_extensions.end()); i != end; ++i) @@ -2561,10 +2565,6 @@ namespace libtorrent { // let the stats fade out to 0 m_stat.second_tick(tick_interval); - m_connections_quota.min = 0; - m_connections_quota.max = 0; - m_uploads_quota.min = 0; - m_uploads_quota.max = 0; return; } @@ -2623,6 +2623,13 @@ namespace libtorrent } accumulator += m_stat; m_stat.second_tick(tick_interval); + + m_time_scaler--; + if (m_time_scaler <= 0) + { + m_time_scaler = 10; + m_policy->pulse(); + } } bool torrent::try_connect_peer() @@ -2631,18 +2638,6 @@ namespace libtorrent return m_policy->connect_one_peer(); } - void torrent::distribute_resources(float tick_interval) - { - INVARIANT_CHECK; - - m_time_scaler--; - if (m_time_scaler <= 0) - { - m_time_scaler = settings().unchoke_interval; - m_policy->pulse(); - } - } - void torrent::async_verify_piece(int piece_index, boost::function const& f) { INVARIANT_CHECK; @@ -2764,10 +2759,10 @@ namespace libtorrent = m_trackers[m_last_working_tracker].url; } - st.num_uploads = m_uploads_quota.used; - st.uploads_limit = m_uploads_quota.given; - st.num_connections = m_connections_quota.used; - st.connections_limit = m_connections_quota.given; + st.num_uploads = -1; + st.uploads_limit = m_max_uploads; + st.num_connections = int(m_connections.size()); + st.connections_limit = m_max_connections; // if we don't have any metadata, stop here if (!valid_metadata())