lt sync 1955

This commit is contained in:
Marcos Pinto 2008-01-19 04:52:22 +00:00
parent d2f6a99778
commit 379eac85c4
11 changed files with 91 additions and 79 deletions

View File

@ -139,17 +139,21 @@ struct bandwidth_manager
} }
#endif #endif
int queue_size() const
{
mutex_t::scoped_lock l(m_mutex);
return m_queue.size();
}
// non prioritized means that, if there's a line for bandwidth, // non prioritized means that, if there's a line for bandwidth,
// others will cut in front of the non-prioritized peers. // others will cut in front of the non-prioritized peers.
// this is used by web seeds // this is used by web seeds
void request_bandwidth(intrusive_ptr<PeerConnection> peer void request_bandwidth(intrusive_ptr<PeerConnection> peer
, int blk , int blk, int priority)
, bool non_prioritized)
{ {
mutex_t::scoped_lock l(m_mutex); mutex_t::scoped_lock l(m_mutex);
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_ASSERT(blk > 0); TORRENT_ASSERT(blk > 0);
TORRENT_ASSERT(!peer->ignore_bandwidth_limits()); TORRENT_ASSERT(!peer->ignore_bandwidth_limits());
// make sure this peer isn't already in line // make sure this peer isn't already in line
@ -163,38 +167,13 @@ struct bandwidth_manager
#endif #endif
TORRENT_ASSERT(peer->max_assignable_bandwidth(m_channel) > 0); TORRENT_ASSERT(peer->max_assignable_bandwidth(m_channel) > 0);
boost::shared_ptr<Torrent> t = peer->associated_torrent().lock(); typename queue_t::reverse_iterator i(m_queue.rbegin());
while (i != m_queue.rend() && priority > i->priority)
if (peer->max_assignable_bandwidth(m_channel) == 0) {
{ ++i->priority;
t->expire_bandwidth(m_channel, blk); ++i;
peer->assign_bandwidth(m_channel, 0); }
return; m_queue.insert(i.base(), bw_queue_entry<PeerConnection>(peer, blk, priority));
}
m_queue.push_back(bw_queue_entry<PeerConnection>(peer, blk, non_prioritized));
if (!non_prioritized)
{
typename queue_t::reverse_iterator i = m_queue.rbegin();
typename queue_t::reverse_iterator j(i);
for (++j; j != m_queue.rend(); ++j)
{
// if the peer's torrent is not the same one
// continue looking for a peer from the same torrent
if (j->peer->associated_torrent().lock() != t)
continue;
// if we found a peer from the same torrent that
// is prioritized, there is no point looking
// any further.
if (!j->non_prioritized) break;
using std::swap;
swap(*i, *j);
i = j;
}
}
#ifdef TORRENT_VERBOSE_BANDWIDTH_LIMIT
std::cerr << " req_bandwidht. m_queue.size() = " << m_queue.size() << std::endl;
#endif
if (!m_queue.empty()) hand_out_bandwidth(l); if (!m_queue.empty()) hand_out_bandwidth(l);
} }
@ -207,8 +186,13 @@ struct bandwidth_manager
{ {
current_quota += i->amount; current_quota += i->amount;
} }
TORRENT_ASSERT(current_quota == m_current_quota); TORRENT_ASSERT(current_quota == m_current_quota);
typename queue_t::const_iterator j = m_queue.begin();
++j;
for (typename queue_t::const_iterator i = m_queue.begin()
, end(m_queue.end()); i != end && j != end; ++i, ++j)
TORRENT_ASSERT(i->priority >= j->priority);
} }
#endif #endif
@ -302,16 +286,14 @@ private:
return; return;
} }
queue_t q;
queue_t tmp; queue_t tmp;
m_queue.swap(q); while (!m_queue.empty() && amount > 0)
while (!q.empty() && amount > 0)
{ {
bw_queue_entry<PeerConnection> qe = q.front(); bw_queue_entry<PeerConnection> qe = m_queue.front();
TORRENT_ASSERT(qe.max_block_size > 0); TORRENT_ASSERT(qe.max_block_size > 0);
q.pop_front(); m_queue.pop_front();
shared_ptr<Torrent> t = qe.peer->associated_torrent().lock(); shared_ptr<Torrent> t = qe.torrent.lock();
if (!t) continue; if (!t) continue;
if (qe.peer->is_disconnecting()) if (qe.peer->is_disconnecting())
{ {
@ -371,11 +353,6 @@ private:
#ifdef TORRENT_VERBOSE_BANDWIDTH_LIMIT #ifdef TORRENT_VERBOSE_BANDWIDTH_LIMIT
std::cerr << " block_size = " << block_size << " amount = " << amount << std::endl; std::cerr << " block_size = " << block_size << " amount = " << amount << std::endl;
#endif #endif
if (amount < block_size / 2)
{
tmp.push_back(qe);
break;
}
// so, hand out max_assignable, but no more than // so, hand out max_assignable, but no more than
// the available bandwidth (amount) and no more // the available bandwidth (amount) and no more
@ -392,7 +369,6 @@ private:
add_history_entry(history_entry<PeerConnection, Torrent>( add_history_entry(history_entry<PeerConnection, Torrent>(
qe.peer, t, hand_out_amount, now + bw_window_size)); qe.peer, t, hand_out_amount, now + bw_window_size));
} }
if (!q.empty()) m_queue.insert(m_queue.begin(), q.begin(), q.end());
if (!tmp.empty()) m_queue.insert(m_queue.begin(), tmp.begin(), tmp.end()); if (!tmp.empty()) m_queue.insert(m_queue.begin(), tmp.begin(), tmp.end());
} }
catch (std::exception& e) catch (std::exception& e)

View File

@ -40,12 +40,15 @@ namespace libtorrent {
template<class PeerConnection> template<class PeerConnection>
struct bw_queue_entry struct bw_queue_entry
{ {
typedef typename PeerConnection::torrent_type torrent_type;
bw_queue_entry(boost::intrusive_ptr<PeerConnection> const& pe bw_queue_entry(boost::intrusive_ptr<PeerConnection> const& pe
, int blk, bool no_prio) , int blk, int prio)
: peer(pe), max_block_size(blk), non_prioritized(no_prio) {} : peer(pe), torrent(peer->associated_torrent())
, max_block_size(blk), priority(prio) {}
boost::intrusive_ptr<PeerConnection> peer; boost::intrusive_ptr<PeerConnection> peer;
boost::weak_ptr<torrent_type> torrent;
int max_block_size; int max_block_size;
bool non_prioritized; int priority; // 0 is low prio
}; };
} }

View File

@ -98,6 +98,8 @@ namespace libtorrent
friend class invariant_access; friend class invariant_access;
public: public:
typedef torrent torrent_type;
enum channels enum channels
{ {
upload_channel, upload_channel,
@ -173,8 +175,8 @@ namespace libtorrent
void request_large_blocks(bool b) void request_large_blocks(bool b)
{ m_request_large_blocks = b; } { m_request_large_blocks = b; }
void set_non_prioritized(bool b) void set_priority(int p)
{ m_non_prioritized = b; } { m_priority = p; }
void fast_reconnect(bool r); void fast_reconnect(bool r);
bool fast_reconnect() const { return m_fast_reconnect; } bool fast_reconnect() const { return m_fast_reconnect; }
@ -683,11 +685,9 @@ namespace libtorrent
// at a time. // at a time.
bool m_request_large_blocks; bool m_request_large_blocks;
// if this is true, other (prioritized) peers will // this is the priority with which this peer gets
// skip ahead of it in the queue for bandwidth. The // download bandwidth quota assigned to it.
// effect is that non prioritized peers will only use int m_priority;
// the left-over bandwidth (suitable for web seeds).
bool m_non_prioritized;
int m_upload_limit; int m_upload_limit;
int m_download_limit; int m_download_limit;

View File

@ -55,6 +55,9 @@ namespace libtorrent
int num_peers; int num_peers;
int up_bandwidth_queue;
int down_bandwidth_queue;
#ifndef TORRENT_DISABLE_DHT #ifndef TORRENT_DISABLE_DHT
int dht_nodes; int dht_nodes;
int dht_node_cache; int dht_node_cache;

View File

@ -229,12 +229,11 @@ namespace libtorrent
void request_bandwidth(int channel void request_bandwidth(int channel
, boost::intrusive_ptr<peer_connection> const& p , boost::intrusive_ptr<peer_connection> const& p
, bool non_prioritized); , int priority);
void perform_bandwidth_request(int channel void perform_bandwidth_request(int channel
, boost::intrusive_ptr<peer_connection> const& p , boost::intrusive_ptr<peer_connection> const& p
, int block_size , int block_size, int priority);
, bool non_prioritized);
void expire_bandwidth(int channel, int amount); void expire_bandwidth(int channel, int amount);
void assign_bandwidth(int channel, int amount, int blk); void assign_bandwidth(int channel, int amount, int blk);

View File

@ -112,6 +112,8 @@ namespace libtorrent
, uploads_limit(0) , uploads_limit(0)
, connections_limit(0) , connections_limit(0)
, storage_mode(storage_mode_sparse) , storage_mode(storage_mode_sparse)
, up_bandwidth_queue(0)
, down_bandwidth_queue(0)
{} {}
enum state_t enum state_t
@ -231,6 +233,9 @@ namespace libtorrent
// true if the torrent is saved in compact mode // true if the torrent is saved in compact mode
// false if it is saved in full allocation mode // false if it is saved in full allocation mode
storage_mode_t storage_mode; storage_mode_t storage_mode;
int up_bandwidth_queue;
int down_bandwidth_queue;
}; };
struct TORRENT_EXPORT block_info struct TORRENT_EXPORT block_info

View File

@ -86,7 +86,7 @@ namespace libtorrent
BN_bn2bin(m_DH->pub_key, (unsigned char*)m_dh_local_key); // TODO Check return value BN_bn2bin(m_DH->pub_key, (unsigned char*)m_dh_local_key); // TODO Check return value
} }
DH_key_exchange::~DH_key_exchange () DH_key_exchange::~DH_key_exchange()
{ {
TORRENT_ASSERT(m_DH); TORRENT_ASSERT(m_DH);
DH_free(m_DH); DH_free(m_DH);
@ -108,6 +108,7 @@ namespace libtorrent
int secret_size = DH_compute_key((unsigned char*)dh_secret int secret_size = DH_compute_key((unsigned char*)dh_secret
, bn_remote_pubkey, m_DH); , bn_remote_pubkey, m_DH);
if (secret_size < 0 || secret_size > 96) throw std::bad_alloc();
if (secret_size != 96) if (secret_size != 96)
{ {
@ -139,3 +140,4 @@ namespace libtorrent
} // namespace libtorrent } // namespace libtorrent
#endif // #ifndef TORRENT_DISABLE_ENCRYPTION #endif // #ifndef TORRENT_DISABLE_ENCRYPTION

View File

@ -109,7 +109,7 @@ namespace libtorrent
, m_reading(false) , m_reading(false)
, m_prefer_whole_pieces(false) , m_prefer_whole_pieces(false)
, m_request_large_blocks(false) , m_request_large_blocks(false)
, m_non_prioritized(false) , m_priority(1)
, m_upload_limit(bandwidth_limit::inf) , m_upload_limit(bandwidth_limit::inf)
, m_download_limit(bandwidth_limit::inf) , m_download_limit(bandwidth_limit::inf)
, m_peer_info(peerinfo) , m_peer_info(peerinfo)
@ -186,7 +186,7 @@ namespace libtorrent
, m_reading(false) , m_reading(false)
, m_prefer_whole_pieces(false) , m_prefer_whole_pieces(false)
, m_request_large_blocks(false) , m_request_large_blocks(false)
, m_non_prioritized(false) , m_priority(1)
, m_upload_limit(bandwidth_limit::inf) , m_upload_limit(bandwidth_limit::inf)
, m_download_limit(bandwidth_limit::inf) , m_download_limit(bandwidth_limit::inf)
, m_peer_info(peerinfo) , m_peer_info(peerinfo)
@ -1742,7 +1742,8 @@ namespace libtorrent
INVARIANT_CHECK; INVARIANT_CHECK;
boost::shared_ptr<torrent> t = m_torrent.lock(); boost::shared_ptr<torrent> t = m_torrent.lock();
TORRENT_ASSERT(t); // this peer might be disconnecting
if (!t) return;
TORRENT_ASSERT(t->valid_metadata()); TORRENT_ASSERT(t->valid_metadata());
@ -2485,7 +2486,7 @@ namespace libtorrent
// peers that we are not interested in are non-prioritized // peers that we are not interested in are non-prioritized
m_writing = true; m_writing = true;
t->request_bandwidth(upload_channel, self() t->request_bandwidth(upload_channel, self()
, !(is_interesting() && !has_peer_choked())); , is_interesting() * 2);
} }
return; return;
} }
@ -2538,7 +2539,7 @@ namespace libtorrent
(*m_logger) << "req bandwidth [ " << download_channel << " ]\n"; (*m_logger) << "req bandwidth [ " << download_channel << " ]\n";
#endif #endif
m_reading = true; m_reading = true;
t->request_bandwidth(download_channel, self(), m_non_prioritized); t->request_bandwidth(download_channel, self(), m_priority);
} }
return; return;
} }

View File

@ -1068,7 +1068,7 @@ namespace detail
} }
// don't allow more connections than the max setting // don't allow more connections than the max setting
if (num_connections() > max_connections()) if (num_connections() >= max_connections())
{ {
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
(*m_logger) << "number of connections limit exceeded (conns: " (*m_logger) << "number of connections limit exceeded (conns: "
@ -2015,6 +2015,10 @@ namespace detail
// INVARIANT_CHECK; // INVARIANT_CHECK;
session_status s; session_status s;
s.up_bandwidth_queue = m_upload_channel.queue_size();
s.down_bandwidth_queue = m_download_channel.queue_size();
s.has_incoming_connections = m_incoming_connection; s.has_incoming_connections = m_incoming_connection;
s.num_peers = (int)m_connections.size(); s.num_peers = (int)m_connections.size();

View File

@ -2222,7 +2222,11 @@ namespace libtorrent
#ifndef NDEBUG #ifndef NDEBUG
std::size_t size = m_connections.size(); std::size_t size = m_connections.size();
#endif #endif
p->disconnect();
if (p->is_disconnecting())
m_connections.erase(m_connections.begin());
else
p->disconnect();
TORRENT_ASSERT(m_connections.size() <= size); TORRENT_ASSERT(m_connections.size() <= size);
} }
} }
@ -2234,7 +2238,7 @@ namespace libtorrent
void torrent::request_bandwidth(int channel void torrent::request_bandwidth(int channel
, boost::intrusive_ptr<peer_connection> const& p , boost::intrusive_ptr<peer_connection> const& p
, bool non_prioritized) , int priority)
{ {
TORRENT_ASSERT(m_bandwidth_limit[channel].throttle() > 0); TORRENT_ASSERT(m_bandwidth_limit[channel].throttle() > 0);
TORRENT_ASSERT(p->max_assignable_bandwidth(channel) > 0); TORRENT_ASSERT(p->max_assignable_bandwidth(channel) > 0);
@ -2243,17 +2247,20 @@ namespace libtorrent
if (m_bandwidth_limit[channel].max_assignable() > 0) if (m_bandwidth_limit[channel].max_assignable() > 0)
{ {
perform_bandwidth_request(channel, p, block_size, non_prioritized); perform_bandwidth_request(channel, p, block_size, priority);
} }
else else
{ {
// skip forward in the queue until we find a prioritized peer // skip forward in the queue until we find a prioritized peer
// or hit the front of it. // or hit the front of it.
queue_t::reverse_iterator i = m_bandwidth_queue[channel].rbegin(); queue_t::reverse_iterator i = m_bandwidth_queue[channel].rbegin();
if (!non_prioritized) while (i != m_bandwidth_queue[channel].rend() && priority > i->priority)
while (i != m_bandwidth_queue[channel].rend() && i->non_prioritized) ++i; {
++i->priority;
++i;
}
m_bandwidth_queue[channel].insert(i.base(), bw_queue_entry<peer_connection>( m_bandwidth_queue[channel].insert(i.base(), bw_queue_entry<peer_connection>(
p, block_size, non_prioritized)); p, block_size, priority));
} }
} }
@ -2277,7 +2284,7 @@ namespace libtorrent
continue; continue;
} }
perform_bandwidth_request(channel, qe.peer perform_bandwidth_request(channel, qe.peer
, qe.max_block_size, qe.non_prioritized); , qe.max_block_size, qe.priority);
} }
m_bandwidth_queue[channel].insert(m_bandwidth_queue[channel].begin(), tmp.begin(), tmp.end()); m_bandwidth_queue[channel].insert(m_bandwidth_queue[channel].begin(), tmp.begin(), tmp.end());
} }
@ -2285,10 +2292,10 @@ namespace libtorrent
void torrent::perform_bandwidth_request(int channel void torrent::perform_bandwidth_request(int channel
, boost::intrusive_ptr<peer_connection> const& p , boost::intrusive_ptr<peer_connection> const& p
, int block_size , int block_size
, bool non_prioritized) , int priority)
{ {
m_ses.m_bandwidth_manager[channel]->request_bandwidth(p m_ses.m_bandwidth_manager[channel]->request_bandwidth(p
, block_size, non_prioritized); , block_size, priority);
m_bandwidth_limit[channel].assign(block_size); m_bandwidth_limit[channel].assign(block_size);
} }
@ -2621,6 +2628,15 @@ namespace libtorrent
TORRENT_ASSERT(m_bandwidth_queue[0].size() <= m_connections.size()); TORRENT_ASSERT(m_bandwidth_queue[0].size() <= m_connections.size());
TORRENT_ASSERT(m_bandwidth_queue[1].size() <= m_connections.size()); TORRENT_ASSERT(m_bandwidth_queue[1].size() <= m_connections.size());
for (int c = 0; c < 2; ++c)
{
queue_t::const_iterator j = m_bandwidth_queue[c].begin();
++j;
for (queue_t::const_iterator i = m_bandwidth_queue[c].begin()
, end(m_bandwidth_queue[c].end()); i != end && j != end; ++i, ++j)
TORRENT_ASSERT(i->priority >= j->priority);
}
int num_uploads = 0; int num_uploads = 0;
std::map<piece_block, int> num_requests; std::map<piece_block, int> num_requests;
for (const_peer_iterator i = begin(); i != end(); ++i) for (const_peer_iterator i = begin(); i != end(); ++i)
@ -3064,6 +3080,9 @@ namespace libtorrent
torrent_status st; torrent_status st;
st.up_bandwidth_queue = (int)m_bandwidth_queue[peer_connection::upload_channel].size();
st.down_bandwidth_queue = (int)m_bandwidth_queue[peer_connection::download_channel].size();
st.num_peers = (int)std::count_if(m_connections.begin(), m_connections.end() st.num_peers = (int)std::count_if(m_connections.begin(), m_connections.end()
, !boost::bind(&peer_connection::is_connecting, _1)); , !boost::bind(&peer_connection::is_connecting, _1));

View File

@ -73,7 +73,7 @@ namespace libtorrent
// we can request more bytes at once // we can request more bytes at once
request_large_blocks(true); request_large_blocks(true);
// we only want left-over bandwidth // we only want left-over bandwidth
set_non_prioritized(true); set_priority(0);
shared_ptr<torrent> tor = t.lock(); shared_ptr<torrent> tor = t.lock();
TORRENT_ASSERT(tor); TORRENT_ASSERT(tor);
int blocks_per_piece = tor->torrent_file().piece_length() / tor->block_size(); int blocks_per_piece = tor->torrent_file().piece_length() / tor->block_size();