more asserts, piece_picker fixes, debug-iterator fixes

This commit is contained in:
Arvid Norberg 2007-08-03 06:13:26 +00:00
parent 192ce4b463
commit 8387240b31
6 changed files with 61 additions and 36 deletions

View File

@ -77,12 +77,6 @@ rule linking ( properties * )
; ;
} }
if ( <toolset>gcc in $(properties) || <toolset>darwin in $(properties) ) && <variant>debug in $(properties)
{
# enable debug iterators for gcc in debug mode
result += <define>_GLIBCXX_DEBUG ;
}
return $(result) ; return $(result) ;
} }
@ -147,6 +141,9 @@ feature.compose <upnp-logging>on : <define>TORRENT_UPNP_LOGGING ;
feature boost : system source : link-incompatible propagated ; feature boost : system source : link-incompatible propagated ;
feature debug-iterators : off on : composite propagated link-incompatible ;
feature.compose <debug-iterators>on : <define>_SCL_SECURE=1 <define>_GLIBCXX_DEBUG ;
# required for openssl on windows # required for openssl on windows
lib ssleay32 : : <name>ssleay32 ; lib ssleay32 : : <name>ssleay32 ;
lib libeay32 : : <name>libeay32 ; lib libeay32 : : <name>libeay32 ;

View File

@ -391,9 +391,7 @@ namespace libtorrent
#ifndef TORRENT_DISABLE_ENCRYPTION #ifndef TORRENT_DISABLE_ENCRYPTION
buffer::interval wr_recv_buffer() buffer::interval wr_recv_buffer()
{ {
#if defined _SECURE_SCL && _SECURE_SCL > 0
if (m_recv_buffer.empty()) return buffer::interval(0,0); if (m_recv_buffer.empty()) return buffer::interval(0,0);
#endif
return buffer::interval(&m_recv_buffer[0] return buffer::interval(&m_recv_buffer[0]
, &m_recv_buffer[0] + m_recv_pos); , &m_recv_buffer[0] + m_recv_pos);
} }
@ -401,9 +399,7 @@ namespace libtorrent
buffer::const_interval receive_buffer() const buffer::const_interval receive_buffer() const
{ {
#if defined _SECURE_SCL && _SECURE_SCL > 0
if (m_recv_buffer.empty()) return buffer::const_interval(0,0); if (m_recv_buffer.empty()) return buffer::const_interval(0,0);
#endif
return buffer::const_interval(&m_recv_buffer[0] return buffer::const_interval(&m_recv_buffer[0]
, &m_recv_buffer[0] + m_recv_pos); , &m_recv_buffer[0] + m_recv_pos);
} }

View File

@ -215,6 +215,9 @@ namespace libtorrent
void mark_as_finished(piece_block block, void* peer); void mark_as_finished(piece_block block, void* peer);
int num_peers(piece_block block) const; int num_peers(piece_block block) const;
// returns information about the given piece
void piece_info(int index, piece_picker::downloading_piece& st) const;
// if a piece had a hash-failure, it must be restored and // if a piece had a hash-failure, it must be restored and
// made available for redownloading // made available for redownloading
void restore_piece(int index); void restore_piece(int index);

View File

@ -129,6 +129,35 @@ namespace libtorrent
} }
} }
void piece_picker::piece_info(int index, piece_picker::downloading_piece& st) const
{
TORRENT_PIECE_PICKER_INVARIANT_CHECK;
assert(index >= 0);
assert(index < int(m_piece_map.size()));
if (m_piece_map[index].downloading)
{
std::vector<downloading_piece>::const_iterator piece = std::find_if(
m_downloads.begin(), m_downloads.end()
, bind(&downloading_piece::index, _1) == index);
assert(piece != m_downloads.end());
st = *piece;
st.info = 0;
return;
}
st.info = 0;
st.index = index;
st.writing = 0;
st.requested = 0;
if (m_piece_map[index].have())
{
st.finished = blocks_in_piece(index);
return;
}
st.finished = 0;
}
void piece_picker::set_sequenced_download_threshold( void piece_picker::set_sequenced_download_threshold(
int sequenced_download_threshold) int sequenced_download_threshold)
{ {
@ -196,13 +225,8 @@ namespace libtorrent
int block_index = num_downloads * m_blocks_per_piece; int block_index = num_downloads * m_blocks_per_piece;
if (int(m_block_info.size()) < block_index + m_blocks_per_piece) if (int(m_block_info.size()) < block_index + m_blocks_per_piece)
{ {
#if defined _SECURE_SCL && _SECURE_SCL > 0
block_info* base = 0; block_info* base = 0;
if (!m_block_info.empty()) if (!m_block_info.empty()) base = &m_block_info[0];
base = &m_block_info[0];
#else
block_info* base = &m_block_info[0];
#endif
m_block_info.resize(block_index + m_blocks_per_piece); m_block_info.resize(block_index + m_blocks_per_piece);
if (!m_downloads.empty() && &m_block_info[0] != base) if (!m_downloads.empty() && &m_block_info[0] != base)
{ {
@ -611,20 +635,15 @@ namespace libtorrent
void piece_picker::sort_piece(std::vector<downloading_piece>::iterator dp) void piece_picker::sort_piece(std::vector<downloading_piece>::iterator dp)
{ {
assert(m_piece_map[dp->index].downloading); assert(m_piece_map[dp->index].downloading);
#if defined _SECURE_SCL && _SECURE_SCL > 0
if (dp == m_downloads.begin()) return; if (dp == m_downloads.begin()) return;
#endif
int complete = dp->writing + dp->finished; int complete = dp->writing + dp->finished;
for (std::vector<downloading_piece>::iterator i = dp, j(dp-1); for (std::vector<downloading_piece>::iterator i = dp, j(dp-1);
i != m_downloads.begin(); --i, --j) i != m_downloads.begin() && j != m_downloads.begin(); --i, --j)
{ {
assert(j >= m_downloads.begin()); assert(j >= m_downloads.begin());
if (j->finished + j->writing >= complete) return; if (j->finished + j->writing >= complete) return;
using std::swap; using std::swap;
swap(*j, *i); swap(*j, *i);
#if defined _SECURE_SCL && _SECURE_SCL > 0
if (j == m_downloads.begin()) return;
#endif
} }
} }
@ -1063,8 +1082,12 @@ namespace libtorrent
// downloaded to // downloaded to
std::vector<piece_block> backup_blocks; std::vector<piece_block> backup_blocks;
// When prefer_whole_pieces is set (usually set when downloading from
// fast peers) the partial pieces will not be prioritized, but actually
// ignored as long as possible. All blocks found in downloading
// pieces are regarded as backup blocks
bool ignore_downloading_pieces = false; bool ignore_downloading_pieces = false;
if (!prefer_whole_pieces) if (prefer_whole_pieces)
{ {
std::vector<int> downloading_pieces; std::vector<int> downloading_pieces;
downloading_pieces.reserve(m_downloads.size()); downloading_pieces.reserve(m_downloads.size());
@ -1073,8 +1096,8 @@ namespace libtorrent
{ {
downloading_pieces.push_back(i->index); downloading_pieces.push_back(i->index);
} }
num_blocks = add_interesting_blocks(downloading_pieces, pieces add_interesting_blocks(downloading_pieces, pieces
, interesting_blocks, backup_blocks, num_blocks , backup_blocks, backup_blocks, num_blocks
, prefer_whole_pieces, peer, speed, ignore_downloading_pieces); , prefer_whole_pieces, peer, speed, ignore_downloading_pieces);
ignore_downloading_pieces = true; ignore_downloading_pieces = true;
} }
@ -1084,10 +1107,6 @@ namespace libtorrent
// has filled the interesting_blocks with num_blocks // has filled the interesting_blocks with num_blocks
// blocks. // blocks.
// When prefer_whole_pieces is set (usually set when downloading from
// fast peers) the partial pieces will not be prioritized, but actually
// ignored as long as possible.
// +1 is to ignore pieces that no peer has. The bucket with index 0 contains // +1 is to ignore pieces that no peer has. The bucket with index 0 contains
// pieces that 0 other peers have. bucket will point to a bucket with // pieces that 0 other peers have. bucket will point to a bucket with
// pieces with the same priority. It will be iterated in priority // pieces with the same priority. It will be iterated in priority
@ -1140,8 +1159,7 @@ namespace libtorrent
if (!backup_blocks.empty()) if (!backup_blocks.empty())
interesting_blocks.insert(interesting_blocks.end() interesting_blocks.insert(interesting_blocks.end()
, backup_blocks.begin(), backup_blocks.begin() , backup_blocks.begin(), backup_blocks.end());
+ (std::min)(num_blocks, (int)backup_blocks.size()));
} }
void piece_picker::clear_peer(void* peer) void piece_picker::clear_peer(void* peer)
@ -1228,7 +1246,6 @@ namespace libtorrent
// will be picked. // will be picked.
if (prefer_whole_pieces && !exclusive) if (prefer_whole_pieces && !exclusive)
{ {
if (int(backup_blocks.size()) >= num_blocks) continue;
for (int j = 0; j < num_blocks_in_piece; ++j) for (int j = 0; j < num_blocks_in_piece; ++j)
{ {
block_info const& info = p->info[j]; block_info const& info = p->info[j];
@ -1263,7 +1280,6 @@ namespace libtorrent
&& !exclusive_active && !exclusive_active
&& !ignore_speed_categories) && !ignore_speed_categories)
{ {
if (int(backup_blocks.size()) >= num_blocks) continue;
backup_blocks.push_back(piece_block(*i, j)); backup_blocks.push_back(piece_block(*i, j));
continue; continue;
} }
@ -1276,9 +1292,9 @@ namespace libtorrent
// to look for blocks until we have num_blocks // to look for blocks until we have num_blocks
// blocks that have not been requested from any // blocks that have not been requested from any
// other peer. // other peer.
interesting_blocks.push_back(piece_block(*i, j));
if (p->info[j].state == block_info::state_none) if (p->info[j].state == block_info::state_none)
{ {
interesting_blocks.push_back(piece_block(*i, j));
// we have found a block that's free to download // we have found a block that's free to download
num_blocks--; num_blocks--;
// if we prefer whole pieces, continue picking from this // if we prefer whole pieces, continue picking from this
@ -1287,6 +1303,10 @@ namespace libtorrent
assert(num_blocks >= 0); assert(num_blocks >= 0);
if (num_blocks == 0) return num_blocks; if (num_blocks == 0) return num_blocks;
} }
else
{
backup_blocks.push_back(piece_block(*i, j));
}
} }
assert(num_blocks >= 0 || prefer_whole_pieces); assert(num_blocks >= 0 || prefer_whole_pieces);
if (num_blocks < 0) num_blocks = 0; if (num_blocks < 0) num_blocks = 0;

View File

@ -249,7 +249,7 @@ namespace libtorrent
// with the other's, to see if we should abort another // with the other's, to see if we should abort another
// peer_connection in favour of this one // peer_connection in favour of this one
std::vector<piece_block> busy_pieces; std::vector<piece_block> busy_pieces;
busy_pieces.reserve(10); busy_pieces.reserve(num_requests);
for (std::vector<piece_block>::iterator i = interesting_pieces.begin(); for (std::vector<piece_block>::iterator i = interesting_pieces.begin();
i != interesting_pieces.end(); ++i) i != interesting_pieces.end(); ++i)
@ -272,6 +272,8 @@ namespace libtorrent
// by somebody else. request it from this peer // by somebody else. request it from this peer
// and return // and return
c.add_request(*i); c.add_request(*i);
assert(p.num_peers(*i) == 1);
assert(p.is_requested(*i));
num_requests--; num_requests--;
} }
@ -286,6 +288,8 @@ namespace libtorrent
return; return;
} }
// if all blocks has the same number of peers on them
// we want to pick a random block
std::random_shuffle(busy_pieces.begin(), busy_pieces.end()); std::random_shuffle(busy_pieces.begin(), busy_pieces.end());
// find the block with the fewest requests to it // find the block with the fewest requests to it
@ -293,7 +297,11 @@ namespace libtorrent
busy_pieces.begin(), busy_pieces.end() busy_pieces.begin(), busy_pieces.end()
, bind(&piece_picker::num_peers, boost::cref(p), _1) < , bind(&piece_picker::num_peers, boost::cref(p), _1) <
bind(&piece_picker::num_peers, boost::cref(p), _2)); bind(&piece_picker::num_peers, boost::cref(p), _2));
#ifndef NDEBUG
piece_picker::downloading_piece st;
p.piece_info(i->piece_index, st);
assert(st.requested + st.finished + st.writing == p.blocks_in_piece(i->piece_index));
#endif
c.add_request(*i); c.add_request(*i);
c.send_block_requests(); c.send_block_requests();
} }

View File

@ -1125,6 +1125,7 @@ namespace libtorrent
j.piece = r.piece; j.piece = r.piece;
j.offset = r.start; j.offset = r.start;
j.buffer_size = r.length; j.buffer_size = r.length;
assert(r.length <= 16 * 1024);
m_io_thread.add_job(j, handler); m_io_thread.add_job(j, handler);
} }