libtorrent sync 1401
This commit is contained in:
parent
e95c399ac5
commit
b06922dcd4
|
@ -391,10 +391,6 @@ private:
|
|||
break;
|
||||
}
|
||||
|
||||
// don't hand out chunks larger than the throttle
|
||||
// per second on the torrent
|
||||
assert(qe.max_block_size <= t->bandwidth_throttle(m_channel));
|
||||
|
||||
// so, hand out max_assignable, but no more than
|
||||
// the available bandwidth (amount) and no more
|
||||
// than the max_bandwidth_block_size
|
||||
|
@ -402,6 +398,7 @@ private:
|
|||
, amount);
|
||||
assert(hand_out_amount > 0);
|
||||
amount -= hand_out_amount;
|
||||
assert(hand_out_amount <= qe.max_block_size);
|
||||
t->assign_bandwidth(m_channel, hand_out_amount, qe.max_block_size);
|
||||
qe.peer->assign_bandwidth(m_channel, hand_out_amount);
|
||||
add_history_entry(history_entry<PeerConnection, Torrent>(
|
||||
|
|
|
@ -88,6 +88,9 @@ private:
|
|||
int m_half_open_limit;
|
||||
|
||||
deadline_timer m_timer;
|
||||
#ifndef NDEBUG
|
||||
bool m_in_timeout_function;
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -279,7 +279,8 @@ namespace libtorrent
|
|||
assert(index_ >= 0);
|
||||
}
|
||||
|
||||
// selects which vector to look in
|
||||
// the number of peers that has this piece
|
||||
// (availability)
|
||||
unsigned peer_count : 10;
|
||||
// is 1 if the piece is marked as being downloaded
|
||||
unsigned downloading : 1;
|
||||
|
@ -350,13 +351,15 @@ namespace libtorrent
|
|||
|
||||
void add(int index);
|
||||
void move(int vec_index, int elem_index);
|
||||
void sort_piece(std::vector<downloading_piece>::iterator dp);
|
||||
|
||||
int add_interesting_blocks(const std::vector<int>& piece_list
|
||||
, const std::vector<bool>& pieces
|
||||
, std::vector<piece_block>& interesting_blocks
|
||||
, std::vector<piece_block>& backup_blocks
|
||||
, int num_blocks, bool prefer_whole_pieces
|
||||
, void* peer, piece_state_t speed) const;
|
||||
, void* peer, piece_state_t speed
|
||||
, bool ignore_downloading_pieces) const;
|
||||
|
||||
downloading_piece& add_download_piece();
|
||||
void erase_download_piece(std::vector<downloading_piece>::iterator i);
|
||||
|
|
|
@ -42,6 +42,9 @@ namespace libtorrent
|
|||
, m_num_connecting(0)
|
||||
, m_half_open_limit(0)
|
||||
, m_timer(ios)
|
||||
#ifndef NDEBUG
|
||||
, m_in_timeout_function(false)
|
||||
#endif
|
||||
{}
|
||||
|
||||
bool connection_queue::free_slots() const
|
||||
|
@ -133,9 +136,22 @@ namespace libtorrent
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
struct function_guard
|
||||
{
|
||||
function_guard(bool& v): val(v) { assert(!val); val = true; }
|
||||
~function_guard() { val = false; }
|
||||
|
||||
bool& val;
|
||||
};
|
||||
#endif
|
||||
|
||||
void connection_queue::on_timeout(asio::error_code const& e)
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
#ifndef NDEBUG
|
||||
function_guard guard_(m_in_timeout_function);
|
||||
#endif
|
||||
|
||||
assert(!e || e == asio::error::operation_aborted);
|
||||
if (e) return;
|
||||
|
|
|
@ -196,12 +196,13 @@ namespace libtorrent
|
|||
int block_index = num_downloads * m_blocks_per_piece;
|
||||
if (int(m_block_info.size()) < block_index + m_blocks_per_piece)
|
||||
{
|
||||
block_info* base = &m_block_info[0];
|
||||
m_block_info.resize(block_index + m_blocks_per_piece);
|
||||
if (!m_downloads.empty() && &m_block_info[0] != m_downloads.front().info)
|
||||
if (!m_downloads.empty() && &m_block_info[0] != base)
|
||||
{
|
||||
// this means the memory was reallocated, update the pointers
|
||||
for (int i = 0; i < int(m_downloads.size()); ++i)
|
||||
m_downloads[i].info = &m_block_info[i * m_blocks_per_piece];
|
||||
m_downloads[i].info = &m_block_info[m_downloads[i].info - base];
|
||||
}
|
||||
}
|
||||
m_downloads.push_back(downloading_piece());
|
||||
|
@ -218,21 +219,18 @@ namespace libtorrent
|
|||
|
||||
void piece_picker::erase_download_piece(std::vector<downloading_piece>::iterator i)
|
||||
{
|
||||
if (i != m_downloads.end() - 1)
|
||||
std::vector<downloading_piece>::iterator other = std::find_if(
|
||||
m_downloads.begin(), m_downloads.end()
|
||||
, bind(&downloading_piece::info, _1)
|
||||
== &m_block_info[(m_downloads.size() - 1) * m_blocks_per_piece]);
|
||||
assert(other != m_downloads.end());
|
||||
|
||||
if (i != other)
|
||||
{
|
||||
int remove_index = i - m_downloads.begin();
|
||||
int last_index = m_downloads.size() - 1;
|
||||
assert(remove_index < last_index);
|
||||
|
||||
assert(int(m_block_info.size()) >= last_index * m_blocks_per_piece + m_blocks_per_piece);
|
||||
std::copy(m_block_info.begin() + (last_index * m_blocks_per_piece)
|
||||
, m_block_info.begin() + (last_index * m_blocks_per_piece + m_blocks_per_piece)
|
||||
, m_block_info.begin() + (remove_index * m_blocks_per_piece));
|
||||
m_downloads[remove_index] = m_downloads[last_index];
|
||||
m_downloads[remove_index].info = &m_block_info[remove_index * m_blocks_per_piece];
|
||||
std::copy(other->info, other->info + m_blocks_per_piece, i->info);
|
||||
other->info = i->info;
|
||||
}
|
||||
|
||||
m_downloads.pop_back();
|
||||
m_downloads.erase(i);
|
||||
}
|
||||
#ifndef NDEBUG
|
||||
|
||||
|
@ -242,6 +240,17 @@ namespace libtorrent
|
|||
|
||||
assert(m_piece_info.empty() || m_piece_info[0].empty());
|
||||
|
||||
if (!m_downloads.empty())
|
||||
{
|
||||
for (std::vector<downloading_piece>::const_iterator i = m_downloads.begin();
|
||||
i != m_downloads.end() - 1; ++i)
|
||||
{
|
||||
downloading_piece const& dp = *i;
|
||||
downloading_piece const& next = *(i + 1);
|
||||
assert(dp.finished + dp.writing >= next.finished + next.writing);
|
||||
}
|
||||
}
|
||||
|
||||
if (t != 0)
|
||||
assert((int)m_piece_map.size() == t->torrent_file().num_pieces());
|
||||
|
||||
|
@ -593,6 +602,20 @@ namespace libtorrent
|
|||
}
|
||||
}
|
||||
|
||||
void piece_picker::sort_piece(std::vector<downloading_piece>::iterator dp)
|
||||
{
|
||||
assert(m_piece_map[dp->index].downloading);
|
||||
int complete = dp->writing + dp->finished;
|
||||
for (std::vector<downloading_piece>::iterator i = dp, j(dp-1);
|
||||
i != m_downloads.begin(); --i, --j)
|
||||
{
|
||||
assert(j >= m_downloads.begin());
|
||||
if (j->finished + j->writing >= complete) return;
|
||||
using std::swap;
|
||||
swap(*j, *i);
|
||||
}
|
||||
}
|
||||
|
||||
void piece_picker::restore_piece(int index)
|
||||
{
|
||||
TORRENT_PIECE_PICKER_INVARIANT_CHECK;
|
||||
|
@ -1027,6 +1050,22 @@ namespace libtorrent
|
|||
// blocks belonging to a piece that others have
|
||||
// downloaded to
|
||||
std::vector<piece_block> backup_blocks;
|
||||
|
||||
bool ignore_downloading_pieces = false;
|
||||
if (!prefer_whole_pieces)
|
||||
{
|
||||
std::vector<int> downloading_pieces;
|
||||
downloading_pieces.reserve(m_downloads.size());
|
||||
for (std::vector<downloading_piece>::const_iterator i = m_downloads.begin()
|
||||
, end(m_downloads.end()); i != end; ++i)
|
||||
{
|
||||
downloading_pieces.push_back(i->index);
|
||||
}
|
||||
num_blocks = add_interesting_blocks(downloading_pieces, pieces
|
||||
, interesting_blocks, backup_blocks, num_blocks
|
||||
, prefer_whole_pieces, peer, speed, ignore_downloading_pieces);
|
||||
ignore_downloading_pieces = true;
|
||||
}
|
||||
|
||||
// this loop will loop from pieces with priority 1 and up
|
||||
// until we either reach the end of the piece list or
|
||||
|
@ -1049,7 +1088,7 @@ namespace libtorrent
|
|||
if (bucket->empty()) continue;
|
||||
num_blocks = add_interesting_blocks(*bucket, pieces
|
||||
, interesting_blocks, backup_blocks, num_blocks
|
||||
, prefer_whole_pieces, peer, speed);
|
||||
, prefer_whole_pieces, peer, speed, ignore_downloading_pieces);
|
||||
assert(num_blocks >= 0);
|
||||
if (num_blocks == 0) return;
|
||||
if (rarest_first) continue;
|
||||
|
@ -1135,7 +1174,8 @@ namespace libtorrent
|
|||
, std::vector<piece_block>& interesting_blocks
|
||||
, std::vector<piece_block>& backup_blocks
|
||||
, int num_blocks, bool prefer_whole_pieces
|
||||
, void* peer, piece_state_t speed) const
|
||||
, void* peer, piece_state_t speed
|
||||
, bool ignore_downloading_pieces) const
|
||||
{
|
||||
// if we have less than 1% of the pieces, ignore speed priorities and just try
|
||||
// to finish any downloading piece
|
||||
|
@ -1154,6 +1194,7 @@ namespace libtorrent
|
|||
|
||||
if (m_piece_map[*i].downloading == 1)
|
||||
{
|
||||
if (ignore_downloading_pieces) continue;
|
||||
std::vector<downloading_piece>::const_iterator p
|
||||
= std::find_if(m_downloads.begin(), m_downloads.end(), has_index(*i));
|
||||
assert(p != m_downloads.end());
|
||||
|
@ -1422,7 +1463,7 @@ namespace libtorrent
|
|||
assert(info.state == block_info::state_requested);
|
||||
if (info.state == block_info::state_requested) --i->requested;
|
||||
assert(i->requested >= 0);
|
||||
assert (info.state != block_info::state_writing);
|
||||
assert(info.state != block_info::state_writing);
|
||||
++i->writing;
|
||||
info.state = block_info::state_writing;
|
||||
if (info.num_peers > 0) --info.num_peers;
|
||||
|
@ -1434,6 +1475,7 @@ namespace libtorrent
|
|||
// remove the fast/slow state from it
|
||||
i->state = none;
|
||||
}
|
||||
sort_piece(i);
|
||||
}
|
||||
|
||||
void piece_picker::mark_as_finished(piece_block block, void* peer)
|
||||
|
@ -1461,9 +1503,11 @@ namespace libtorrent
|
|||
block_info& info = dp.info[block.block_index];
|
||||
info.peer = peer;
|
||||
assert(info.state == block_info::state_none);
|
||||
// if (info.state == block_info::state_writing) --dp.writing;
|
||||
// assert(dp.writing >= 0);
|
||||
if (info.state != block_info::state_finished) ++dp.finished;
|
||||
if (info.state != block_info::state_finished)
|
||||
{
|
||||
++dp.finished;
|
||||
sort_piece(m_downloads.end() - 1);
|
||||
}
|
||||
info.state = block_info::state_finished;
|
||||
}
|
||||
else
|
||||
|
@ -1477,16 +1521,17 @@ namespace libtorrent
|
|||
info.peer = peer;
|
||||
assert(info.state == block_info::state_writing
|
||||
|| peer == 0);
|
||||
if (info.state == block_info::state_writing) --i->writing;
|
||||
assert(i->writing >= 0);
|
||||
++i->finished;
|
||||
info.state = block_info::state_finished;
|
||||
|
||||
if (i->requested == 0)
|
||||
if (info.state == block_info::state_writing)
|
||||
{
|
||||
// there are no blocks requested in this piece.
|
||||
// remove the fast/slow state from it
|
||||
i->state = none;
|
||||
--i->writing;
|
||||
info.state = block_info::state_finished;
|
||||
}
|
||||
else
|
||||
{
|
||||
info.state = block_info::state_finished;
|
||||
sort_piece(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2010,8 +2010,6 @@ namespace libtorrent
|
|||
, int block_size
|
||||
, bool non_prioritized)
|
||||
{
|
||||
assert(m_bandwidth_limit[channel].max_assignable() >= block_size);
|
||||
|
||||
m_ses.m_bandwidth_manager[channel]->request_bandwidth(p
|
||||
, block_size, non_prioritized);
|
||||
m_bandwidth_limit[channel].assign(block_size);
|
||||
|
|
Loading…
Reference in New Issue