From c69479a166ce4025bda5ef9c848b8f3785a1bbe2 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Fri, 22 Dec 2006 00:45:43 +0000 Subject: [PATCH] fixed the cause of an inconsistency in the piece picker and the torrent --- src/peer_connection.cpp | 72 +++++++++++++++++++++++++++++------------ src/piece_picker.cpp | 7 +++- src/torrent.cpp | 3 +- 3 files changed, 60 insertions(+), 22 deletions(-) diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index d86d819cd..b85115bb3 100755 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -940,7 +940,38 @@ namespace libtorrent { m_last_piece = second_clock::universal_time(); } + +#ifndef NDEBUG + struct check_postcondition + { + check_postcondition(boost::shared_ptr const& t_ + , bool init_check = true): t(t_) { if (init_check) check(); } + ~check_postcondition() { check(); } + + void check() + { + if (!t->is_seed()) + { + const int blocks_per_piece = static_cast( + t->torrent_file().piece_length() / t->block_size()); + + std::vector const& dl_queue + = t->picker().get_download_queue(); + + for (std::vector::const_iterator i = + dl_queue.begin(); i != dl_queue.end(); ++i) + { + assert(int(i->finished_blocks.count()) < blocks_per_piece); + } + } + } + + shared_ptr t; + }; +#endif + + // ----------------------------- // ----------- PIECE ----------- // ----------------------------- @@ -952,6 +983,7 @@ namespace libtorrent boost::shared_ptr t = m_torrent.lock(); assert(t); #ifndef NDEBUG + check_postcondition post_checker_(t); t->check_invariant(); #endif @@ -1073,9 +1105,18 @@ namespace libtorrent fs.write(data, p.piece, p.start, p.length); picker.mark_as_finished(block_finished, m_remote); - t->get_policy().block_finished(*this, block_finished); - send_block_requests(); + try + { + t->get_policy().block_finished(*this, block_finished); + send_block_requests(); + } + catch (std::exception const&) {} + +#ifndef NDEBUG + try + { +#endif bool was_seed = t->is_seed(); bool was_finished = picker.num_filtered() + t->num_pieces() @@ -1084,6 +1125,9 @@ namespace libtorrent // did we just finish the piece? if (picker.is_piece_finished(p.piece)) { +#ifndef NDEBUG + check_postcondition post_checker2_(t, false); +#endif bool verified = t->verify_piece(p.piece); if (verified) { @@ -1113,22 +1157,6 @@ namespace libtorrent { t->piece_failed(p.piece); } -#ifndef NDEBUG - if (!t->is_seed()) - { - const int blocks_per_piece = static_cast( - t->torrent_file().piece_length() / t->block_size()); - - std::vector const& dl_queue - = t->picker().get_download_queue(); - - for (std::vector::const_iterator i = - dl_queue.begin(); i != dl_queue.end(); ++i) - { - assert(int(i->finished_blocks.count()) < blocks_per_piece); - } - } -#endif t->get_policy().piece_finished(p.piece, verified); @@ -1138,9 +1166,13 @@ namespace libtorrent t->completed(); } } - #ifndef NDEBUG - t->check_invariant(); + } + catch (std::exception const& e) + { + std::string err = e.what(); + assert(false); + } #endif } diff --git a/src/piece_picker.cpp b/src/piece_picker.cpp index 9dde4d271..93445e0b6 100755 --- a/src/piece_picker.cpp +++ b/src/piece_picker.cpp @@ -965,7 +965,12 @@ namespace libtorrent assert(index < (int)m_piece_map.size()); assert(index >= 0); - if (m_piece_map[index].downloading == 0) return false; + if (m_piece_map[index].downloading == 0) + { + assert(std::find_if(m_downloads.begin(), m_downloads.end(), has_index(index)) + == m_downloads.end()); + return false; + } std::vector::const_iterator i = std::find_if(m_downloads.begin(), m_downloads.end(), has_index(index)); assert(i != m_downloads.end()); diff --git a/src/torrent.cpp b/src/torrent.cpp index 32e21a1f8..ee4cdc2f0 100755 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -734,7 +734,8 @@ namespace libtorrent { int corr = 0; assert(!m_have_pieces[i->index]); - assert(int(i->finished_blocks.count()) < blocks_per_piece); + assert(int(i->finished_blocks.count()) + < m_torrent_file.piece_size(i->index) / m_block_size); #ifndef NDEBUG for (std::vector::const_iterator j = boost::next(i);