From 1f44ec75a0023c412898c28582b121b794d83067 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Sat, 1 May 2010 17:47:28 +0000 Subject: [PATCH] fixed bug in add_piece() that would trigger asserts --- ChangeLog | 1 + include/libtorrent/piece_picker.hpp | 5 ++++- src/piece_picker.cpp | 8 ++++++-- src/torrent.cpp | 4 +++- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9785e615b..7c663aea8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -28,6 +28,7 @@ incoming connection * added more detailed instrumentation of the disk I/O thread + * fixed bug in add_piece() that would trigger asserts * fixed vs 2010 build * recognizes more clients in identify_client() * fixed bug where trackers wouldn't be retried if they failed diff --git a/include/libtorrent/piece_picker.hpp b/include/libtorrent/piece_picker.hpp index c2ea3322e..b354cd3f8 100644 --- a/include/libtorrent/piece_picker.hpp +++ b/include/libtorrent/piece_picker.hpp @@ -276,7 +276,10 @@ namespace libtorrent // marks this piece-block as queued for downloading bool mark_as_downloading(piece_block block, void* peer , piece_state_t s); - void mark_as_writing(piece_block block, void* peer); + // returns true if the block was marked as writing, + // and false if the block is already finished or writing + bool mark_as_writing(piece_block block, void* peer); + void mark_as_finished(piece_block block, void* peer); void write_failed(piece_block block); int num_peers(piece_block block) const; diff --git a/src/piece_picker.cpp b/src/piece_picker.cpp index 80bb6653f..04a4ccd51 100644 --- a/src/piece_picker.cpp +++ b/src/piece_picker.cpp @@ -2089,7 +2089,7 @@ namespace libtorrent *j = i->peer_count + m_seeds; } - void piece_picker::mark_as_writing(piece_block block, void* peer) + bool piece_picker::mark_as_writing(piece_block block, void* peer) { #ifdef TORRENT_EXPENSIVE_INVARIANT_CHECKS TORRENT_PIECE_PICKER_INVARIANT_CHECK; @@ -2133,7 +2133,10 @@ namespace libtorrent info.peer = peer; if (info.state == block_info::state_requested) --i->requested; TORRENT_ASSERT(i->requested >= 0); - TORRENT_ASSERT(info.state != block_info::state_writing); + if (info.state == block_info::state_writing + || info.state == block_info::state_finished) + return false; + ++i->writing; info.state = block_info::state_writing; @@ -2149,6 +2152,7 @@ namespace libtorrent } sort_piece(i); } + return true; } void piece_picker::write_failed(piece_block block) diff --git a/src/torrent.cpp b/src/torrent.cpp index 21ac2c719..e74062792 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -676,7 +676,9 @@ namespace libtorrent // avoid crash trying to access the picker when there is nont if (is_seed()) return; - if (picker().have_piece(piece)) return; + if (picker().have_piece(piece) + && (flags & torrent::overwrite_existing) == 0) + return; peer_request p; p.piece = piece;