mirror of
https://github.com/codex-storage/deluge.git
synced 2025-01-29 20:56:31 +00:00
lt sync
This commit is contained in:
parent
42f4d55db2
commit
9972471231
120
libtorrent/include/libtorrent/bandwidth_limit.hpp
Normal file
120
libtorrent/include/libtorrent/bandwidth_limit.hpp
Normal file
@ -0,0 +1,120 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2007, 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.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TORRENT_BANDWIDTH_LIMIT_HPP_INCLUDED
|
||||
#define TORRENT_BANDWIDTH_LIMIT_HPP_INCLUDED
|
||||
|
||||
#include <boost/integer_traits.hpp>
|
||||
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent {
|
||||
|
||||
// member of peer_connection
|
||||
struct bandwidth_limit
|
||||
{
|
||||
static const int inf = boost::integer_traits<int>::const_max;
|
||||
|
||||
bandwidth_limit()
|
||||
: m_quota_left(0)
|
||||
, m_local_limit(inf)
|
||||
, m_current_rate(0)
|
||||
{}
|
||||
|
||||
void throttle(int limit)
|
||||
{
|
||||
TORRENT_ASSERT(limit > 0);
|
||||
m_local_limit = limit;
|
||||
}
|
||||
|
||||
int throttle() const
|
||||
{
|
||||
return m_local_limit;
|
||||
}
|
||||
|
||||
void assign(int amount)
|
||||
{
|
||||
TORRENT_ASSERT(amount >= 0);
|
||||
m_current_rate += amount;
|
||||
m_quota_left += amount;
|
||||
}
|
||||
|
||||
void use_quota(int amount)
|
||||
{
|
||||
TORRENT_ASSERT(amount <= m_quota_left);
|
||||
m_quota_left -= amount;
|
||||
}
|
||||
|
||||
int quota_left() const
|
||||
{
|
||||
return (std::max)(m_quota_left, 0);
|
||||
}
|
||||
|
||||
void expire(int amount)
|
||||
{
|
||||
TORRENT_ASSERT(amount >= 0);
|
||||
m_current_rate -= amount;
|
||||
}
|
||||
|
||||
int max_assignable() const
|
||||
{
|
||||
if (m_local_limit == inf) return inf;
|
||||
if (m_local_limit <= m_current_rate) return 0;
|
||||
return m_local_limit - m_current_rate;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// this is the amount of bandwidth we have
|
||||
// been assigned without using yet. i.e.
|
||||
// the bandwidth that we use up every time
|
||||
// we receive or send a message. Once this
|
||||
// hits zero, we need to request more
|
||||
// bandwidth from the torrent which
|
||||
// in turn will request bandwidth from
|
||||
// the bandwidth manager
|
||||
int m_quota_left;
|
||||
|
||||
// the local limit is the number of bytes
|
||||
// per window size we are allowed to use.
|
||||
int m_local_limit;
|
||||
|
||||
// the current rate is the number of
|
||||
// bytes we have been assigned within
|
||||
// the window size.
|
||||
int m_current_rate;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -44,6 +44,8 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "libtorrent/socket.hpp"
|
||||
#include "libtorrent/invariant_check.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
#include "libtorrent/bandwidth_limit.hpp"
|
||||
#include "libtorrent/bandwidth_queue_entry.hpp"
|
||||
|
||||
using boost::weak_ptr;
|
||||
using boost::shared_ptr;
|
||||
@ -77,91 +79,6 @@ struct history_entry
|
||||
weak_ptr<Torrent> tor;
|
||||
};
|
||||
|
||||
template<class PeerConnection>
|
||||
struct bw_queue_entry
|
||||
{
|
||||
bw_queue_entry(boost::intrusive_ptr<PeerConnection> const& pe
|
||||
, int blk, bool no_prio)
|
||||
: peer(pe), max_block_size(blk), non_prioritized(no_prio) {}
|
||||
boost::intrusive_ptr<PeerConnection> peer;
|
||||
int max_block_size;
|
||||
bool non_prioritized;
|
||||
};
|
||||
|
||||
// member of peer_connection
|
||||
struct bandwidth_limit
|
||||
{
|
||||
static const int inf = boost::integer_traits<int>::const_max;
|
||||
|
||||
bandwidth_limit() throw()
|
||||
: m_quota_left(0)
|
||||
, m_local_limit(inf)
|
||||
, m_current_rate(0)
|
||||
{}
|
||||
|
||||
void throttle(int limit) throw()
|
||||
{
|
||||
m_local_limit = limit;
|
||||
}
|
||||
|
||||
int throttle() const throw()
|
||||
{
|
||||
return m_local_limit;
|
||||
}
|
||||
|
||||
void assign(int amount) throw()
|
||||
{
|
||||
TORRENT_ASSERT(amount >= 0);
|
||||
m_current_rate += amount;
|
||||
m_quota_left += amount;
|
||||
}
|
||||
|
||||
void use_quota(int amount) throw()
|
||||
{
|
||||
TORRENT_ASSERT(amount <= m_quota_left);
|
||||
m_quota_left -= amount;
|
||||
}
|
||||
|
||||
int quota_left() const throw()
|
||||
{
|
||||
return (std::max)(m_quota_left, 0);
|
||||
}
|
||||
|
||||
void expire(int amount) throw()
|
||||
{
|
||||
TORRENT_ASSERT(amount >= 0);
|
||||
m_current_rate -= amount;
|
||||
}
|
||||
|
||||
int max_assignable() const throw()
|
||||
{
|
||||
if (m_local_limit == inf) return inf;
|
||||
if (m_local_limit <= m_current_rate) return 0;
|
||||
return m_local_limit - m_current_rate;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// this is the amount of bandwidth we have
|
||||
// been assigned without using yet. i.e.
|
||||
// the bandwidth that we use up every time
|
||||
// we receive or send a message. Once this
|
||||
// hits zero, we need to request more
|
||||
// bandwidth from the torrent which
|
||||
// in turn will request bandwidth from
|
||||
// the bandwidth manager
|
||||
int m_quota_left;
|
||||
|
||||
// the local limit is the number of bytes
|
||||
// per window size we are allowed to use.
|
||||
int m_local_limit;
|
||||
|
||||
// the current rate is the number of
|
||||
// bytes we have been assigned within
|
||||
// the window size.
|
||||
int m_current_rate;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
T clamp(T val, T ceiling, T floor) throw()
|
||||
{
|
||||
@ -203,6 +120,18 @@ struct bandwidth_manager
|
||||
m_history_timer.cancel();
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
bool is_in_history(PeerConnection const* peer) const
|
||||
{
|
||||
for (typename history_t::const_iterator i
|
||||
= m_history.begin(), end(m_history.end()); i != end; ++i)
|
||||
{
|
||||
if (i->peer.get() == peer) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// non prioritized means that, if there's a line for bandwidth,
|
||||
// others will cut in front of the non-prioritized peers.
|
||||
// this is used by web seeds
|
||||
@ -224,6 +153,7 @@ struct bandwidth_manager
|
||||
TORRENT_ASSERT(i->peer < peer || peer < i->peer);
|
||||
}
|
||||
#endif
|
||||
TORRENT_ASSERT(peer->max_assignable_bandwidth(m_channel) > 0);
|
||||
|
||||
boost::shared_ptr<Torrent> t = peer->associated_torrent().lock();
|
||||
|
||||
@ -369,12 +299,21 @@ private:
|
||||
<< " m_current_quota = " << m_current_quota << std::endl;
|
||||
#endif
|
||||
|
||||
while (!m_queue.empty() && amount > 0)
|
||||
if (amount <= 0)
|
||||
{
|
||||
m_in_hand_out_bandwidth = false;
|
||||
return;
|
||||
}
|
||||
|
||||
queue_t q;
|
||||
queue_t tmp;
|
||||
m_queue.swap(q);
|
||||
while (!q.empty() && amount > 0)
|
||||
{
|
||||
TORRENT_ASSERT(amount == limit - m_current_quota);
|
||||
bw_queue_entry<PeerConnection> qe = m_queue.front();
|
||||
bw_queue_entry<PeerConnection> qe = q.front();
|
||||
TORRENT_ASSERT(qe.max_block_size > 0);
|
||||
m_queue.pop_front();
|
||||
q.pop_front();
|
||||
|
||||
shared_ptr<Torrent> t = qe.peer->associated_torrent().lock();
|
||||
if (!t) continue;
|
||||
@ -386,17 +325,13 @@ private:
|
||||
}
|
||||
|
||||
// at this point, max_assignable may actually be zero. Since
|
||||
// the bandwidth quota is subtracted once the data has been
|
||||
// sent. If the peer was added to the queue while the data was
|
||||
// still being sent, max_assignable may have been > 0 at that time.
|
||||
int max_assignable = (std::min)(
|
||||
qe.peer->max_assignable_bandwidth(m_channel)
|
||||
, t->max_assignable_bandwidth(m_channel));
|
||||
// the rate limit of the peer might have changed while it
|
||||
// was in the queue.
|
||||
int max_assignable = qe.peer->max_assignable_bandwidth(m_channel);
|
||||
if (max_assignable == 0)
|
||||
{
|
||||
t->expire_bandwidth(m_channel, qe.max_block_size);
|
||||
qe.peer->assign_bandwidth(m_channel, 0);
|
||||
TORRENT_ASSERT(amount == limit - m_current_quota);
|
||||
TORRENT_ASSERT(is_in_history(qe.peer.get()));
|
||||
tmp.push_back(qe);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -441,7 +376,7 @@ private:
|
||||
#endif
|
||||
if (amount < block_size / 2)
|
||||
{
|
||||
m_queue.push_front(qe);
|
||||
tmp.push_back(qe);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -460,6 +395,8 @@ private:
|
||||
qe.peer, t, hand_out_amount, now + bw_window_size));
|
||||
TORRENT_ASSERT(amount == limit - m_current_quota);
|
||||
}
|
||||
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());
|
||||
#ifndef NDEBUG
|
||||
}
|
||||
catch (std::exception& e)
|
||||
|
54
libtorrent/include/libtorrent/bandwidth_queue_entry.hpp
Normal file
54
libtorrent/include/libtorrent/bandwidth_queue_entry.hpp
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2007, 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.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TORRENT_BANDWIDTH_QUEUE_ENTRY_HPP_INCLUDED
|
||||
#define TORRENT_BANDWIDTH_QUEUE_ENTRY_HPP_INCLUDED
|
||||
|
||||
#include <boost/intrusive_ptr.hpp>
|
||||
|
||||
namespace libtorrent {
|
||||
|
||||
template<class PeerConnection>
|
||||
struct bw_queue_entry
|
||||
{
|
||||
bw_queue_entry(boost::intrusive_ptr<PeerConnection> const& pe
|
||||
, int blk, bool no_prio)
|
||||
: peer(pe), max_block_size(blk), non_prioritized(no_prio) {}
|
||||
boost::intrusive_ptr<PeerConnection> peer;
|
||||
int max_block_size;
|
||||
bool non_prioritized;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -69,7 +69,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "libtorrent/piece_block_progress.hpp"
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/session.hpp"
|
||||
#include "libtorrent/bandwidth_manager.hpp"
|
||||
#include "libtorrent/bandwidth_limit.hpp"
|
||||
#include "libtorrent/policy.hpp"
|
||||
#include "libtorrent/socket_type.hpp"
|
||||
#include "libtorrent/intrusive_ptr_base.hpp"
|
||||
|
@ -65,7 +65,8 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "libtorrent/piece_picker.hpp"
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/escape_string.hpp"
|
||||
#include "libtorrent/bandwidth_manager.hpp"
|
||||
#include "libtorrent/bandwidth_limit.hpp"
|
||||
#include "libtorrent/bandwidth_queue_entry.hpp"
|
||||
#include "libtorrent/storage.hpp"
|
||||
#include "libtorrent/hasher.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
@ -1399,10 +1399,8 @@ namespace libtorrent
|
||||
|
||||
if (t->alerts().should_post(alert::fatal))
|
||||
{
|
||||
if (j.str != "write failed: No space left on device"){
|
||||
std::string err = "torrent paused: disk write error, " + j.str;
|
||||
t->alerts().post_alert(file_error_alert(t->get_handle(), err));
|
||||
}
|
||||
std::string err = "torrent paused: disk write error, " + j.str;
|
||||
t->alerts().post_alert(file_error_alert(t->get_handle(), err));
|
||||
}
|
||||
t->pause();
|
||||
return;
|
||||
@ -2564,6 +2562,7 @@ namespace libtorrent
|
||||
// return value is destructed
|
||||
buffer::interval peer_connection::allocate_send_buffer(int size)
|
||||
{
|
||||
TORRENT_ASSERT(size > 0);
|
||||
char* insert = m_send_buffer.allocate_appendix(size);
|
||||
if (insert == 0)
|
||||
{
|
||||
@ -2871,6 +2870,13 @@ namespace libtorrent
|
||||
#ifndef NDEBUG
|
||||
void peer_connection::check_invariant() const
|
||||
{
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
// this peer is in the bandwidth history iff max_assignable < limit
|
||||
TORRENT_ASSERT((m_bandwidth_limit[i].max_assignable() < m_bandwidth_limit[i].throttle())
|
||||
== m_ses.m_bandwidth_manager[i]->is_in_history(this)
|
||||
|| m_bandwidth_limit[i].throttle() == bandwidth_limit::inf);
|
||||
}
|
||||
if (m_peer_info)
|
||||
{
|
||||
TORRENT_ASSERT(m_peer_info->connection == this
|
||||
|
@ -2225,6 +2225,7 @@ namespace libtorrent
|
||||
, bool non_prioritized)
|
||||
{
|
||||
TORRENT_ASSERT(m_bandwidth_limit[channel].throttle() > 0);
|
||||
TORRENT_ASSERT(p->max_assignable_bandwidth(channel) > 0);
|
||||
int block_size = m_bandwidth_limit[channel].throttle() / 10;
|
||||
if (block_size <= 0) block_size = 1;
|
||||
|
||||
@ -2249,16 +2250,23 @@ namespace libtorrent
|
||||
|
||||
TORRENT_ASSERT(amount > 0);
|
||||
m_bandwidth_limit[channel].expire(amount);
|
||||
|
||||
queue_t tmp;
|
||||
while (!m_bandwidth_queue[channel].empty())
|
||||
{
|
||||
bw_queue_entry<peer_connection> qe = m_bandwidth_queue[channel].front();
|
||||
if (m_bandwidth_limit[channel].max_assignable() == 0)
|
||||
break;
|
||||
m_bandwidth_queue[channel].pop_front();
|
||||
if (qe.peer->max_assignable_bandwidth(channel) <= 0)
|
||||
{
|
||||
TORRENT_ASSERT(m_ses.m_bandwidth_manager[channel]->is_in_history(qe.peer.get()));
|
||||
if (!qe.peer->is_disconnecting()) tmp.push_back(qe);
|
||||
continue;
|
||||
}
|
||||
perform_bandwidth_request(channel, qe.peer
|
||||
, qe.max_block_size, qe.non_prioritized);
|
||||
}
|
||||
m_bandwidth_queue[channel].insert(m_bandwidth_queue[channel].begin(), tmp.begin(), tmp.end());
|
||||
}
|
||||
|
||||
void torrent::perform_bandwidth_request(int channel
|
||||
|
Loading…
x
Reference in New Issue
Block a user