From 8387240b31ee917bebbc8816eb2c4cde9d83cd85 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Fri, 3 Aug 2007 06:13:26 +0000 Subject: [PATCH] more asserts, piece_picker fixes, debug-iterator fixes --- Jamfile | 9 ++-- include/libtorrent/peer_connection.hpp | 4 -- include/libtorrent/piece_picker.hpp | 3 ++ src/piece_picker.cpp | 68 +++++++++++++++++--------- src/policy.cpp | 12 ++++- src/storage.cpp | 1 + 6 files changed, 61 insertions(+), 36 deletions(-) diff --git a/Jamfile b/Jamfile index fc2bf8104..905e7bad2 100755 --- a/Jamfile +++ b/Jamfile @@ -77,12 +77,6 @@ rule linking ( properties * ) ; } - if ( gcc in $(properties) || darwin in $(properties) ) && debug in $(properties) - { - # enable debug iterators for gcc in debug mode - result += _GLIBCXX_DEBUG ; - } - return $(result) ; } @@ -147,6 +141,9 @@ feature.compose on : TORRENT_UPNP_LOGGING ; feature boost : system source : link-incompatible propagated ; +feature debug-iterators : off on : composite propagated link-incompatible ; +feature.compose on : _SCL_SECURE=1 _GLIBCXX_DEBUG ; + # required for openssl on windows lib ssleay32 : : ssleay32 ; lib libeay32 : : libeay32 ; diff --git a/include/libtorrent/peer_connection.hpp b/include/libtorrent/peer_connection.hpp index caac2f63c..9006a546d 100755 --- a/include/libtorrent/peer_connection.hpp +++ b/include/libtorrent/peer_connection.hpp @@ -391,9 +391,7 @@ namespace libtorrent #ifndef TORRENT_DISABLE_ENCRYPTION buffer::interval wr_recv_buffer() { -#if defined _SECURE_SCL && _SECURE_SCL > 0 if (m_recv_buffer.empty()) return buffer::interval(0,0); -#endif return buffer::interval(&m_recv_buffer[0] , &m_recv_buffer[0] + m_recv_pos); } @@ -401,9 +399,7 @@ namespace libtorrent buffer::const_interval receive_buffer() const { -#if defined _SECURE_SCL && _SECURE_SCL > 0 if (m_recv_buffer.empty()) return buffer::const_interval(0,0); -#endif return buffer::const_interval(&m_recv_buffer[0] , &m_recv_buffer[0] + m_recv_pos); } diff --git a/include/libtorrent/piece_picker.hpp b/include/libtorrent/piece_picker.hpp index 136e71c63..9595e2501 100755 --- a/include/libtorrent/piece_picker.hpp +++ b/include/libtorrent/piece_picker.hpp @@ -215,6 +215,9 @@ namespace libtorrent void mark_as_finished(piece_block block, void* peer); 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 // made available for redownloading void restore_piece(int index); diff --git a/src/piece_picker.cpp b/src/piece_picker.cpp index 7691bd384..833ceb793 100755 --- a/src/piece_picker.cpp +++ b/src/piece_picker.cpp @@ -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::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( int sequenced_download_threshold) { @@ -196,13 +225,8 @@ namespace libtorrent int block_index = num_downloads * 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; - if (!m_block_info.empty()) - base = &m_block_info[0]; -#else - block_info* base = &m_block_info[0]; -#endif + if (!m_block_info.empty()) base = &m_block_info[0]; m_block_info.resize(block_index + m_blocks_per_piece); if (!m_downloads.empty() && &m_block_info[0] != base) { @@ -611,20 +635,15 @@ namespace libtorrent void piece_picker::sort_piece(std::vector::iterator dp) { assert(m_piece_map[dp->index].downloading); -#if defined _SECURE_SCL && _SECURE_SCL > 0 if (dp == m_downloads.begin()) return; -#endif int complete = dp->writing + dp->finished; for (std::vector::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()); if (j->finished + j->writing >= complete) return; using std::swap; 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 std::vector 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; - if (!prefer_whole_pieces) + if (prefer_whole_pieces) { std::vector downloading_pieces; downloading_pieces.reserve(m_downloads.size()); @@ -1073,8 +1096,8 @@ namespace libtorrent { downloading_pieces.push_back(i->index); } - num_blocks = add_interesting_blocks(downloading_pieces, pieces - , interesting_blocks, backup_blocks, num_blocks + add_interesting_blocks(downloading_pieces, pieces + , backup_blocks, backup_blocks, num_blocks , prefer_whole_pieces, peer, speed, ignore_downloading_pieces); ignore_downloading_pieces = true; } @@ -1084,10 +1107,6 @@ namespace libtorrent // has filled the interesting_blocks with num_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 // pieces that 0 other peers have. bucket will point to a bucket with // pieces with the same priority. It will be iterated in priority @@ -1140,8 +1159,7 @@ namespace libtorrent if (!backup_blocks.empty()) interesting_blocks.insert(interesting_blocks.end() - , backup_blocks.begin(), backup_blocks.begin() - + (std::min)(num_blocks, (int)backup_blocks.size())); + , backup_blocks.begin(), backup_blocks.end()); } void piece_picker::clear_peer(void* peer) @@ -1228,7 +1246,6 @@ namespace libtorrent // will be picked. if (prefer_whole_pieces && !exclusive) { - if (int(backup_blocks.size()) >= num_blocks) continue; for (int j = 0; j < num_blocks_in_piece; ++j) { block_info const& info = p->info[j]; @@ -1263,7 +1280,6 @@ namespace libtorrent && !exclusive_active && !ignore_speed_categories) { - if (int(backup_blocks.size()) >= num_blocks) continue; backup_blocks.push_back(piece_block(*i, j)); continue; } @@ -1276,9 +1292,9 @@ namespace libtorrent // to look for blocks until we have num_blocks // blocks that have not been requested from any // other peer. - interesting_blocks.push_back(piece_block(*i, j)); 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 num_blocks--; // if we prefer whole pieces, continue picking from this @@ -1287,6 +1303,10 @@ namespace libtorrent assert(num_blocks >= 0); if (num_blocks == 0) return num_blocks; } + else + { + backup_blocks.push_back(piece_block(*i, j)); + } } assert(num_blocks >= 0 || prefer_whole_pieces); if (num_blocks < 0) num_blocks = 0; diff --git a/src/policy.cpp b/src/policy.cpp index 2f0d24b08..572f48d35 100755 --- a/src/policy.cpp +++ b/src/policy.cpp @@ -249,7 +249,7 @@ namespace libtorrent // with the other's, to see if we should abort another // peer_connection in favour of this one std::vector busy_pieces; - busy_pieces.reserve(10); + busy_pieces.reserve(num_requests); for (std::vector::iterator i = interesting_pieces.begin(); i != interesting_pieces.end(); ++i) @@ -272,6 +272,8 @@ namespace libtorrent // by somebody else. request it from this peer // and return c.add_request(*i); + assert(p.num_peers(*i) == 1); + assert(p.is_requested(*i)); num_requests--; } @@ -286,6 +288,8 @@ namespace libtorrent 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()); // find the block with the fewest requests to it @@ -293,7 +297,11 @@ namespace libtorrent busy_pieces.begin(), busy_pieces.end() , bind(&piece_picker::num_peers, boost::cref(p), _1) < 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.send_block_requests(); } diff --git a/src/storage.cpp b/src/storage.cpp index 793f95365..313ee6254 100755 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -1125,6 +1125,7 @@ namespace libtorrent j.piece = r.piece; j.offset = r.start; j.buffer_size = r.length; + assert(r.length <= 16 * 1024); m_io_thread.add_job(j, handler); }