From d6dc5b52e4ceaca2395692de4d623f207131607a Mon Sep 17 00:00:00 2001 From: Magnus Jonsson Date: Thu, 11 Mar 2004 14:56:48 +0000 Subject: [PATCH] *** empty log message *** --- include/libtorrent/allocate_resources.hpp | 1 + include/libtorrent/peer_connection.hpp | 113 ++++++------------- src/allocate_resources.cpp | 7 +- src/peer_connection.cpp | 129 ++++++++++++++++++++-- src/session.cpp | 10 +- src/torrent_handle.cpp | 8 +- 6 files changed, 163 insertions(+), 105 deletions(-) diff --git a/include/libtorrent/allocate_resources.hpp b/include/libtorrent/allocate_resources.hpp index 389c09a73..c8b474493 100644 --- a/include/libtorrent/allocate_resources.hpp +++ b/include/libtorrent/allocate_resources.hpp @@ -39,6 +39,7 @@ POSSIBILITY OF SUCH DAMAGE. namespace libtorrent { struct resource_request { + resource_request() : used(0), wanted(0), given(0) { } // I'm right now actively using: diff --git a/include/libtorrent/peer_connection.hpp b/include/libtorrent/peer_connection.hpp index 5d7458be3..955d12116 100755 --- a/include/libtorrent/peer_connection.hpp +++ b/include/libtorrent/peer_connection.hpp @@ -131,11 +131,7 @@ namespace libtorrent // this adds an announcement in the announcement queue // it will let the peer know that we have the given piece - void announce_piece(int index) - { - assert(index >= 0 && index < m_torrent->torrent_file().num_pieces()); - m_announce_queue.push_back(index); - } + void announce_piece(int index); // called from the main loop when this connection has any // work to do. @@ -153,17 +149,10 @@ namespace libtorrent void keep_alive(); const peer_id& id() const { return m_peer_id; } - bool has_piece(int i) const - { - assert(i >= 0); - assert(i < m_torrent->torrent_file().num_pieces()); - return m_have_piece[i]; - } + bool has_piece(int i) const; - const std::deque& download_queue() const - { return m_download_queue; } - const std::deque& upload_queue() const - { return m_requests; } + const std::deque& download_queue() const; + const std::deque& upload_queue() const; // returns the block currently being // downloaded. And the progress of that @@ -187,8 +176,7 @@ namespace libtorrent bool verify_piece(const peer_request& p) const; const stat& statistics() const { return m_statistics; } - void add_stat(size_type downloaded, size_type uploaded) - { m_statistics.add_stat(downloaded, uploaded); } + void add_stat(size_type downloaded, size_type uploaded); // is called once every second by the main loop void second_tick(); @@ -196,63 +184,42 @@ namespace libtorrent boost::shared_ptr get_socket() const { return m_socket; } const peer_id& get_peer_id() const { return m_peer_id; } - const std::vector& get_bitfield() const - { return m_have_piece; } + const std::vector& get_bitfield() const; // this will cause this peer_connection to be disconnected. // what it does is that it puts a reference to it in // m_ses.m_disconnect_peer list, which will be scanned in the // mainloop to disconnect peers. void disconnect(); - - bool is_disconnecting() const - { return m_disconnecting; } - - resource_request upload_bandwidth; + bool is_disconnecting() const { return m_disconnecting; } // returns the send quota this peer has // left until will stop sending. // if the send_quota is -1, it means the // quota is unlimited. - int send_quota_left() const { return upload_bandwidth.given-upload_bandwidth.used; } + int send_quota_left() const; + resource_request* upload_bandwidth_quota(); - void update_send_quota_left() - { - upload_bandwidth.used=0; - send_buffer_updated(); - } + // ?? TODO: document + void update_send_quota_left(); - size_type total_free_upload() const - { return m_free_upload; } - - void add_free_upload(size_type free_upload) - { m_free_upload += free_upload; } + // free upload. + size_type total_free_upload() const; + void add_free_upload(size_type free_upload); - void received_valid_data() - { - m_trust_points++; - if (m_trust_points > 20) m_trust_points = 20; - } - - void received_invalid_data() - { - m_trust_points--; - if (m_trust_points < -5) m_trust_points = -5; - } - - int trust_points() const - { return m_trust_points; } + // trust management. + void received_valid_data(); + void received_invalid_data(); + int trust_points() const; size_type share_diff() const; - bool support_extensions() const - { return m_supports_extensions; } + bool support_extensions() const { return m_supports_extensions; } // a connection is local if it was initiated by us. // if it was an incoming connection, it is remote - bool is_local() const - { return m_active; } + bool is_local() const { return m_active; } #ifndef NDEBUG boost::shared_ptr m_logger; @@ -300,6 +267,11 @@ namespace libtorrent void check_invariant() const; bool dispatch_message(int received); + + + // this is called each time this peer generates some + // data to be sent. It will add this socket to + // the writibility monitor in the selector. void send_buffer_updated(); // is used during handshake @@ -379,6 +351,14 @@ namespace libtorrent selector& m_selector; boost::shared_ptr m_socket; + // how much bandwidth we're using, how much we want, + // and how much we are allowed to use. + resource_request m_upload_bandwidth_quota; + + // upload bandwidth used this second. + // Must not exceed m_upload_bandwidth_quota.given. + int m_upload_bandwidth_quota_used; + // this is the torrent this connection is // associated with. If the connection is an // incoming conncetion, this is set to zero @@ -508,33 +488,6 @@ namespace libtorrent // this peer the last time. boost::posix_time::ptime m_became_uninteresting; }; - - // this is called each time this peer generates some - // data to be sent. It will add this socket to - // the writibility monitor in the selector. - inline void peer_connection::send_buffer_updated() - { - if (!has_data()) - { - if (m_added_to_selector) - { - m_selector.remove_writable(m_socket); - m_added_to_selector = false; - } - assert(!m_selector.is_writability_monitored(m_socket)); - return; - } - - assert(upload_bandwidth.used < upload_bandwidth.given); - assert(has_data()); - if (!m_added_to_selector) - { - m_selector.monitor_writability(m_socket); - m_added_to_selector = true; - } - assert(m_added_to_selector); - assert(m_selector.is_writability_monitored(m_socket)); - } } #endif // TORRENT_PEER_CONNECTION_HPP_INCLUDED diff --git a/src/allocate_resources.cpp b/src/allocate_resources.cpp index 41f246272..42019779b 100644 --- a/src/allocate_resources.cpp +++ b/src/allocate_resources.cpp @@ -153,12 +153,11 @@ namespace libtorrent #endif } // namespace unnamed - void allocate_resources(int resources - , std::vector& requests) + void allocate_resources(int resources, + std::vector& requests) { #ifndef NDEBUG - allocate_resources_contract_check - contract_check(resources,requests); + allocate_resources_contract_check contract_check(resources,requests); #endif if(resources == std::numeric_limits::max()) diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index be4b6cb63..baeb44fab 100755 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -106,6 +106,7 @@ namespace libtorrent , m_disconnecting(false) , m_became_uninterested(boost::posix_time::second_clock::local_time()) , m_became_uninteresting(boost::posix_time::second_clock::local_time()) + , m_upload_bandwidth_quota_used(0) { INVARIANT_CHECK; @@ -167,6 +168,7 @@ namespace libtorrent , m_disconnecting(false) , m_became_uninterested(boost::posix_time::second_clock::local_time()) , m_became_uninteresting(boost::posix_time::second_clock::local_time()) + , m_upload_bandwidth_quota_used(0) { INVARIANT_CHECK; @@ -202,6 +204,85 @@ namespace libtorrent } } + void peer_connection::announce_piece(int index) + { + assert(m_torrent); + assert(index >= 0 && index < m_torrent->torrent_file().num_pieces()); + m_announce_queue.push_back(index); + } + + bool peer_connection::has_piece(int i) const + { + assert(m_torrent); + assert(i >= 0); + assert(i < m_torrent->torrent_file().num_pieces()); + return m_have_piece[i]; + } + + const std::deque& peer_connection::download_queue() const + { + return m_download_queue; + } + + const std::deque& peer_connection::upload_queue() const + { + return m_requests; + } + + void peer_connection::add_stat(size_type downloaded, size_type uploaded) + { + m_statistics.add_stat(downloaded, uploaded); + } + + const std::vector& peer_connection::get_bitfield() const + { + return m_have_piece; + } + + void peer_connection::received_valid_data() + { + m_trust_points++; + if (m_trust_points > 20) m_trust_points = 20; + } + + void peer_connection::received_invalid_data() + { + m_trust_points--; + if (m_trust_points < -5) m_trust_points = -5; + } + + int peer_connection::trust_points() const + { + return m_trust_points; + } + + size_type peer_connection::total_free_upload() const + { + return m_free_upload; + } + + void peer_connection::add_free_upload(size_type free_upload) + { + m_free_upload += free_upload; + } + + int peer_connection::send_quota_left() const + { + return m_upload_bandwidth_quota.given - m_upload_bandwidth_quota_used; + } + + void peer_connection::update_send_quota_left() + { + m_upload_bandwidth_quota_used=0; + send_buffer_updated(); + } + + resource_request* peer_connection::upload_bandwidth_quota() + { + return &m_upload_bandwidth_quota; + } + + void peer_connection::send_handshake() { INVARIANT_CHECK; @@ -1219,6 +1300,7 @@ namespace libtorrent INVARIANT_CHECK; m_statistics.second_tick(); + m_upload_bandwidth_quota.used=(int)ceil(statistics().upload_rate()); // update_send_quota_left(); @@ -1235,9 +1317,9 @@ namespace libtorrent // than we have uploaded OR if we are a seed // have an unlimited upload rate if(!m_send_buffer.empty() || (!m_requests.empty() && !is_choked())) - upload_bandwidth.wanted = std::numeric_limits::max(); + m_upload_bandwidth_quota.wanted = std::numeric_limits::max(); else - upload_bandwidth.wanted = 1; + m_upload_bandwidth_quota.wanted = 1; } else { @@ -1262,7 +1344,7 @@ namespace libtorrent upload_speed_limit=std::min(upload_speed_limit, (double)std::numeric_limits::max()); - upload_bandwidth.wanted = (int) upload_speed_limit; + m_upload_bandwidth_quota.wanted = (int) upload_speed_limit; } /* @@ -1277,7 +1359,7 @@ namespace libtorrent // if we have downloaded more than one piece more // than we have uploaded OR if we are a seed // have an unlimited upload rate - upload_bandwidth.wanted = std::numeric_limits::max(); + m_upload_bandwidth_quota.wanted = std::numeric_limits::max(); } else { @@ -1296,10 +1378,10 @@ namespace libtorrent { bias = -static_cast(m_statistics.download_rate() * ratio) / 2; } - upload_bandwidth.wanted = static_cast(m_statistics.download_rate()) + bias; + m_upload_bandwidth_quota.wanted = static_cast(m_statistics.download_rate()) + bias; // the maximum send_quota given our download rate from this peer - if (upload_bandwidth.wanted < 256) upload_bandwidth.wanted = 256; + if (m_upload_bandwidth_quota.wanted < 256) m_upload_bandwidth_quota.wanted = 256; } */ } @@ -1576,7 +1658,7 @@ namespace libtorrent // we want to send data return ((!m_requests.empty() && !m_choked) || !m_send_buffer.empty()) - && upload_bandwidth.used < upload_bandwidth.given; + && send_quota_left()>0; } // -------------------------- @@ -1655,15 +1737,15 @@ namespace libtorrent m_announce_queue.clear(); } - assert(upload_bandwidth.used < upload_bandwidth.given); + assert(m_upload_bandwidth_quota_used < m_upload_bandwidth_quota.given); // send the actual buffer if (!m_send_buffer.empty()) { int amount_to_send = (int)m_send_buffer.size(); - assert(upload_bandwidth.used < upload_bandwidth.given); - amount_to_send = std::min(upload_bandwidth.given-upload_bandwidth.used, amount_to_send); + amount_to_send = std::min(send_quota_left(), amount_to_send); + assert(amount_to_send>0); // we have data that's scheduled for sending int sent = m_socket->send( @@ -1672,7 +1754,7 @@ namespace libtorrent if (sent > 0) { - upload_bandwidth.used += sent; + m_upload_bandwidth_quota_used += sent; // manage the payload markers int amount_payload = 0; @@ -1809,4 +1891,29 @@ namespace libtorrent { return m_num_pieces == (int)m_have_piece.size(); } + + void peer_connection::send_buffer_updated() + { + if (!has_data()) + { + if (m_added_to_selector) + { + m_selector.remove_writable(m_socket); + m_added_to_selector = false; + } + assert(!m_selector.is_writability_monitored(m_socket)); + return; + } + + assert(send_quota_left()>0); + assert(has_data()); + if (!m_added_to_selector) + { + m_selector.monitor_writability(m_socket); + m_added_to_selector = true; + } + assert(m_added_to_selector); + assert(m_selector.is_writability_monitored(m_socket)); + } + } diff --git a/src/session.cpp b/src/session.cpp index 5818d14c5..e9f5508b9 100755 --- a/src/session.cpp +++ b/src/session.cpp @@ -110,9 +110,7 @@ namespace c != connections.end(); ++c) { boost::shared_ptr p = c->second; - p->upload_bandwidth.used = (int)ceil(p->statistics().upload_rate()); - - requests.push_back(&p->upload_bandwidth); + requests.push_back(p->upload_bandwidth_quota()); } allocate_resources(upload_limit, requests); @@ -530,7 +528,7 @@ namespace libtorrent { namespace detail if (m_upload_rate != -1) { - c->upload_bandwidth.given = 0; + c->upload_bandwidth_quota()->given = 0; c->update_send_quota_left(); } @@ -786,7 +784,7 @@ namespace libtorrent { namespace detail "peer_connection::has_data() != is_writability_monitored()\n"; error_log << "peer_connection::has_data() " << p->has_data() << "\n"; error_log << "peer_connection::send_quota_left " << p->send_quota_left() << "\n"; - error_log << "peer_connection::upload_bandwidth.given " << p->upload_bandwidth.given << "\n"; + error_log << "peer_connection::upload_bandwidth_quota()->given " << p->upload_bandwidth_quota()->given << "\n"; error_log << "peer_connection::get_peer_id " << p->get_peer_id() << "\n"; error_log << "place: " << place << "\n"; error_log.flush(); @@ -992,7 +990,7 @@ namespace libtorrent = m_impl.m_connections.begin(); i != m_impl.m_connections.end();) { - i->second->upload_bandwidth.given = std::numeric_limits::max(); + i->second->upload_bandwidth_quota()->given = std::numeric_limits::max(); i->second->update_send_quota_left(); } } diff --git a/src/torrent_handle.cpp b/src/torrent_handle.cpp index 0720c9dae..f8595af42 100755 --- a/src/torrent_handle.cpp +++ b/src/torrent_handle.cpp @@ -530,15 +530,15 @@ namespace libtorrent p.total_download = statistics.total_payload_download(); p.total_upload = statistics.total_payload_upload(); - if (peer->upload_bandwidth.given == std::numeric_limits::max()) + if (peer->upload_bandwidth_quota()->given == std::numeric_limits::max()) p.upload_limit = -1; else - p.upload_limit = peer->upload_bandwidth.given; + p.upload_limit = peer->upload_bandwidth_quota()->given; - if (peer->upload_bandwidth.wanted == std::numeric_limits::max()) + if (peer->upload_bandwidth_quota()->wanted == std::numeric_limits::max()) p.upload_ceiling = -1; else - p.upload_ceiling = peer->upload_bandwidth.wanted; + p.upload_ceiling = peer->upload_bandwidth_quota()->wanted; p.load_balancing = peer->total_free_upload();