fixed failing invariant check in peer_connection's download queue

This commit is contained in:
Arvid Norberg 2010-10-03 22:06:53 +00:00
parent 8e4addf2c5
commit f11b1ce6a0
4 changed files with 22 additions and 11 deletions

View File

@ -307,7 +307,7 @@ namespace libtorrent
// clears the given piece's download flag // clears the given piece's download flag
// this means that this piece-block can be picked again // this means that this piece-block can be picked again
void abort_download(piece_block block); void abort_download(piece_block block, void* peer);
bool is_piece_finished(int index) const; bool is_piece_finished(int index) const;

View File

@ -1204,7 +1204,7 @@ namespace libtorrent
for (std::vector<pending_block>::const_iterator i = m_request_queue.begin() for (std::vector<pending_block>::const_iterator i = m_request_queue.begin()
, end(m_request_queue.end()); i != end; ++i) , end(m_request_queue.end()); i != end; ++i)
{ {
p.abort_download(i->block); p.abort_download(i->block, peer_info_struct());
} }
} }
m_request_queue.clear(); m_request_queue.clear();
@ -1272,7 +1272,7 @@ namespace libtorrent
else if (!t->is_seed() && remove_from_picker) else if (!t->is_seed() && remove_from_picker)
{ {
piece_picker& p = t->picker(); piece_picker& p = t->picker();
p.abort_download(b.block); p.abort_download(b.block, peer_info_struct());
} }
#if !defined TORRENT_DISABLE_INVARIANT_CHECKS && defined TORRENT_DEBUG #if !defined TORRENT_DISABLE_INVARIANT_CHECKS && defined TORRENT_DEBUG
check_invariant(); check_invariant();
@ -2294,7 +2294,7 @@ namespace libtorrent
"dqs: " << int(m_desired_queue_size) << "] ***\n"; "dqs: " << int(m_desired_queue_size) << "] ***\n";
#endif #endif
if (!qe.timed_out && !qe.not_wanted) if (!qe.timed_out && !qe.not_wanted)
picker.abort_download(qe.block); picker.abort_download(qe.block, peer_info_struct());
TORRENT_ASSERT(m_outstanding_bytes >= t->to_req(qe.block).length); TORRENT_ASSERT(m_outstanding_bytes >= t->to_req(qe.block).length);
m_outstanding_bytes -= t->to_req(qe.block).length; m_outstanding_bytes -= t->to_req(qe.block).length;
@ -2812,7 +2812,7 @@ namespace libtorrent
while (!m_request_queue.empty()) while (!m_request_queue.empty())
{ {
t->picker().abort_download(m_request_queue.back().block); t->picker().abort_download(m_request_queue.back().block, peer_info_struct());
m_request_queue.pop_back(); m_request_queue.pop_back();
} }
m_queued_time_critical = 0; m_queued_time_critical = 0;
@ -2882,7 +2882,7 @@ namespace libtorrent
// the block, just ignore to cancel it. // the block, just ignore to cancel it.
if (rit == m_request_queue.end()) return; if (rit == m_request_queue.end()) return;
t->picker().abort_download(block); t->picker().abort_download(block, peer_info_struct());
m_request_queue.erase(rit); m_request_queue.erase(rit);
// since we found it in the request queue, it means it hasn't been // since we found it in the request queue, it means it hasn't been
// sent yet, so we don't have to send a cancel. // sent yet, so we don't have to send a cancel.
@ -3073,7 +3073,7 @@ namespace libtorrent
if (t->picker().is_finished(block.block) if (t->picker().is_finished(block.block)
|| t->picker().is_downloaded(block.block)) || t->picker().is_downloaded(block.block))
{ {
t->picker().abort_download(block.block); t->picker().abort_download(block.block, peer_info_struct());
continue; continue;
} }
@ -3269,14 +3269,15 @@ namespace libtorrent
while (!m_download_queue.empty()) while (!m_download_queue.empty())
{ {
pending_block& qe = m_download_queue.back(); pending_block& qe = m_download_queue.back();
if (!qe.timed_out && !qe.not_wanted) picker.abort_download(qe.block); if (!qe.timed_out && !qe.not_wanted)
picker.abort_download(qe.block, peer_info_struct());
m_outstanding_bytes -= t->to_req(qe.block).length; m_outstanding_bytes -= t->to_req(qe.block).length;
if (m_outstanding_bytes < 0) m_outstanding_bytes = 0; if (m_outstanding_bytes < 0) m_outstanding_bytes = 0;
m_download_queue.pop_back(); m_download_queue.pop_back();
} }
while (!m_request_queue.empty()) while (!m_request_queue.empty())
{ {
picker.abort_download(m_request_queue.back().block); picker.abort_download(m_request_queue.back().block, peer_info_struct());
m_request_queue.pop_back(); m_request_queue.pop_back();
} }
} }
@ -4011,7 +4012,7 @@ namespace libtorrent
m_timeout_extend += m_ses.settings().request_timeout; m_timeout_extend += m_ses.settings().request_timeout;
if (r != piece_block::invalid) if (r != piece_block::invalid)
picker.abort_download(r); picker.abort_download(r, peer_info_struct());
send_block_requests(); send_block_requests();
} }
@ -5100,6 +5101,8 @@ namespace libtorrent
boost::shared_ptr<torrent> t = m_torrent.lock(); boost::shared_ptr<torrent> t = m_torrent.lock();
if (m_disconnecting) if (m_disconnecting)
{ {
TORRENT_ASSERT(m_download_queue.empty());
TORRENT_ASSERT(m_request_queue.empty());
TORRENT_ASSERT(!t); TORRENT_ASSERT(!t);
TORRENT_ASSERT(m_disconnect_started); TORRENT_ASSERT(m_disconnect_started);
} }

View File

@ -2305,7 +2305,7 @@ namespace libtorrent
// this is called when a request is rejected or when // this is called when a request is rejected or when
// a peer disconnects. The piece might be in any state // a peer disconnects. The piece might be in any state
void piece_picker::abort_download(piece_block block) void piece_picker::abort_download(piece_block block, void* peer)
{ {
#ifdef TORRENT_EXPENSIVE_INVARIANT_CHECKS #ifdef TORRENT_EXPENSIVE_INVARIANT_CHECKS
TORRENT_PIECE_PICKER_INVARIANT_CHECK; TORRENT_PIECE_PICKER_INVARIANT_CHECK;
@ -2340,6 +2340,7 @@ namespace libtorrent
{ {
TORRENT_ASSERT(info.num_peers > 0); TORRENT_ASSERT(info.num_peers > 0);
if (info.num_peers > 0) --info.num_peers; if (info.num_peers > 0) --info.num_peers;
if (info.peer == peer) info.peer = 0;
TORRENT_ASSERT(block.block_index < blocks_in_piece(block.piece_index)); TORRENT_ASSERT(block.block_index < blocks_in_piece(block.piece_index));

View File

@ -2482,7 +2482,13 @@ namespace libtorrent
// this piece failed the check as it can restore it // this piece failed the check as it can restore it
// and mark it as being interesting for download // and mark it as being interesting for download
m_picker->restore_piece(index); m_picker->restore_piece(index);
// we might still have outstanding requests to this
// piece that hasn't been received yet. If this is the
// case, we need to re-open the piece and mark any
// blocks we're still waiting for as requested
restore_piece_state(index); restore_piece_state(index);
TORRENT_ASSERT(m_storage); TORRENT_ASSERT(m_storage);
TORRENT_ASSERT(m_picker->have_piece(index) == false); TORRENT_ASSERT(m_picker->have_piece(index) == false);
@ -2512,6 +2518,7 @@ namespace libtorrent
for (std::vector<pending_block>::const_iterator k = dq.begin() for (std::vector<pending_block>::const_iterator k = dq.begin()
, end(dq.end()); k != end; ++k) , end(dq.end()); k != end; ++k)
{ {
if (k->timed_out || k->not_wanted) continue;
if (k->block.piece_index != index) continue; if (k->block.piece_index != index) continue;
m_picker->mark_as_downloading(k->block, p->peer_info_struct() m_picker->mark_as_downloading(k->block, p->peer_info_struct()
, (piece_picker::piece_state_t)p->peer_speed()); , (piece_picker::piece_state_t)p->peer_speed());