diff --git a/src/http_connection.cpp b/src/http_connection.cpp index 072a48e97..0442d455c 100644 --- a/src/http_connection.cpp +++ b/src/http_connection.cpp @@ -59,6 +59,8 @@ void http_connection::get(std::string const& url, time_duration timeout, int pri int port; boost::tie(protocol, auth, hostname, port, path) = parse_url_components(url); + TORRENT_ASSERT(prio >= 0 && prio < 2); + bool ssl = false; if (protocol == "https") ssl = true; #ifndef TORRENT_USE_OPENSSL @@ -110,6 +112,8 @@ void http_connection::start(std::string const& hostname, std::string const& port , time_duration timeout, int prio, proxy_settings const* ps, bool ssl, int handle_redirects , address const& bind_addr) { + TORRENT_ASSERT(prio >= 0 && prio < 2); + m_redirects = handle_redirects; if (ps) m_proxy = *ps; diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index 884998fc2..ac362ef42 100755 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -1413,38 +1413,7 @@ namespace libtorrent , m_download_queue.end() , block_finished); - if (b != m_download_queue.end()) - { - if (m_assume_fifo) - { - for (std::deque::iterator i = m_download_queue.begin(); - i != b; ++i) - { -#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING - (*m_logger) << time_now_string() - << " *** SKIPPED_PIECE [ piece: " << i->piece_index << " | " - "b: " << i->block_index << " ] ***\n"; -#endif - // since this piece was skipped, clear it and allow it to - // be requested from other peers - // TODO: send cancel? - picker.abort_download(*i); - } - - // remove the request that just finished - // from the download queue plus the - // skipped blocks. - m_download_queue.erase(m_download_queue.begin() - , boost::next(b)); - } - else - { - m_download_queue.erase(b); - } - - t->cancel_block(block_finished); - } - else + if (b == m_download_queue.end()) { if (t->alerts().should_post(alert::debug)) { @@ -1464,11 +1433,36 @@ namespace libtorrent return; } + if (m_assume_fifo) + { + for (std::deque::iterator i = m_download_queue.begin(); + i != b; ++i) + { +#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING + (*m_logger) << time_now_string() + << " *** SKIPPED_PIECE [ piece: " << i->piece_index << " | " + "b: " << i->block_index << " ] ***\n"; +#endif + // since this piece was skipped, clear it and allow it to + // be requested from other peers + // TODO: send cancel? + picker.abort_download(*i); + } + + // remove the request that just finished + // from the download queue plus the + // skipped blocks. + m_download_queue.erase(m_download_queue.begin(), b); + b = m_download_queue.begin(); + TORRENT_ASSERT(*b == block_finished); + } + // if the block we got is already finished, then ignore it if (picker.is_downloaded(block_finished)) { t->received_redundant_data(p.length); + m_download_queue.erase(b); request_a_block(*t, *this); send_block_requests(); return; @@ -1478,7 +1472,9 @@ namespace libtorrent , self(), _1, _2, p, t)); m_outstanding_writing_bytes += p.length; TORRENT_ASSERT(m_channel_state[download_channel] == peer_info::bw_idle); + m_download_queue.erase(b); picker.mark_as_writing(block_finished, peer_info_struct()); + t->cancel_block(block_finished); #if !defined NDEBUG && !defined TORRENT_DISABLE_INVARIANT_CHECKS t->check_invariant(); #endif diff --git a/src/storage.cpp b/src/storage.cpp index f57af370b..34380af22 100755 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -1536,6 +1536,11 @@ namespace libtorrent m_piece_to_slot.resize(m_info->num_pieces(), has_no_slot); m_slot_to_piece.clear(); m_slot_to_piece.resize(m_info->num_pieces(), unallocated); + if (m_storage_mode == storage_mode_compact) + { + m_unallocated_slots.clear(); + m_free_slots.clear(); + } return need_full_check; } } @@ -1547,7 +1552,9 @@ namespace libtorrent TORRENT_ASSERT(m_unallocated_slots.empty()); for (int i = 0, end(m_info->num_pieces()); i < end; ++i) m_unallocated_slots.push_back(i); + m_piece_to_slot.clear(); m_piece_to_slot.resize(m_info->num_pieces(), has_no_slot); + m_slot_to_piece.clear(); m_slot_to_piece.resize(m_info->num_pieces(), unallocated); } diff --git a/src/torrent.cpp b/src/torrent.cpp index b08906141..91bb1bfb4 100755 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -1795,6 +1795,8 @@ namespace libtorrent void torrent::cancel_block(piece_block block) { + INVARIANT_CHECK; + for (peer_iterator i = m_connections.begin() , end(m_connections.end()); i != end; ++i) { @@ -2400,8 +2402,9 @@ namespace libtorrent TORRENT_ASSERT(p != 0); TORRENT_ASSERT(!p->is_local()); - if (m_state == torrent_status::queued_for_checking + if ((m_state == torrent_status::queued_for_checking || m_state == torrent_status::checking_files) + && valid_metadata()) { p->disconnect("torrent is not ready to accept peers"); return; diff --git a/test/test_http_connection.cpp b/test/test_http_connection.cpp index 57dee078a..c91d187da 100644 --- a/test/test_http_connection.cpp +++ b/test/test_http_connection.cpp @@ -75,7 +75,7 @@ void run_test(std::string const& url, int size, int status, int connected boost::shared_ptr h(new http_connection(ios, cq , &::http_handler, true, &::http_connect_handler)); - h->get(url, seconds(30), &ps); + h->get(url, seconds(30), 0, &ps); ios.reset(); ios.run(); diff --git a/test/test_piece_picker.cpp b/test/test_piece_picker.cpp index e31d559ed..cbe72190e 100644 --- a/test/test_piece_picker.cpp +++ b/test/test_piece_picker.cpp @@ -39,17 +39,11 @@ boost::shared_ptr setup_picker( std::vector have = string2vec(have_str); - std::vector unfinished; - piece_picker::downloading_piece pp; - std::vector blocks(blocks_per_piece * num_pieces); - for (int i = 0; i < num_pieces; ++i) { if (partial[i] == 0) break; if (partial[i] == ' ') continue; - pp.index = i; - pp.info = &blocks[i * blocks_per_piece]; int blocks = 0; if (partial[i] >= '0' && partial[i] <= '9') @@ -57,15 +51,35 @@ boost::shared_ptr setup_picker( else blocks = partial[i] - 'a' + 10; + int counter = 0; if (blocks & 1) - pp.info[0].state = piece_picker::block_info::state_finished; + { + ++counter; + p->mark_as_finished(piece_block(i, 0), 0); + } if (blocks & 2) - pp.info[1].state = piece_picker::block_info::state_finished; + { + ++counter; + p->mark_as_finished(piece_block(i, 1), 0); + } if (blocks & 4) - pp.info[2].state = piece_picker::block_info::state_finished; + { + ++counter; + p->mark_as_finished(piece_block(i, 2), 0); + } if (blocks & 8) - pp.info[3].state = piece_picker::block_info::state_finished; - unfinished.push_back(pp); + { + ++counter; + p->mark_as_finished(piece_block(i, 3), 0); + } + + piece_picker::downloading_piece st; + p->piece_info(i, st); + TEST_CHECK(st.writing == 0); + TEST_CHECK(st.requested == 0); + TEST_CHECK(st.index == i); + + TEST_CHECK(st.finished == counter); } for (int i = 0; i < num_pieces; ++i) @@ -78,26 +92,7 @@ boost::shared_ptr setup_picker( TEST_CHECK(p->piece_priority(i) == prio); } - std::vector verify_pieces; - p->files_checked(have, unfinished, verify_pieces); - - for (std::vector::iterator i = unfinished.begin() - , end(unfinished.end()); i != end; ++i) - { - for (int j = 0; j < blocks_per_piece; ++j) - TEST_CHECK(p->is_finished(piece_block(i->index, j)) == (i->info[j].state == piece_picker::block_info::state_finished)); - - piece_picker::downloading_piece st; - p->piece_info(i->index, st); - TEST_CHECK(st.writing == 0); - TEST_CHECK(st.requested == 0); - TEST_CHECK(st.index == i->index); - int counter = 0; - for (int j = 0; j < blocks_per_piece; ++j) - if (i->info[j].state == piece_picker::block_info::state_finished) ++counter; - - TEST_CHECK(st.finished == counter); - } + p->init(have); for (int i = 0; i < num_pieces; ++i) { diff --git a/test/test_storage.cpp b/test/test_storage.cpp index b437a56af..adeb5f792 100644 --- a/test/test_storage.cpp +++ b/test/test_storage.cpp @@ -25,6 +25,16 @@ void on_read_piece(int ret, disk_io_job const& j, char const* data, int size) TEST_CHECK(std::equal(j.buffer, j.buffer + ret, data)); } +void on_check_resume_data(int ret, disk_io_job const& j) +{ + std::cerr << "on_check_resume_data ret: " << ret << " " << j.piece << std::endl; +} + +void on_check_files(int ret, disk_io_job const& j) +{ + std::cerr << "on_check_files ret: " << ret << " " << j.piece << std::endl; +} + void run_storage_tests(boost::intrusive_ptr info , path const& test_path , libtorrent::storage_mode_t storage_mode) @@ -90,28 +100,15 @@ void run_storage_tests(boost::intrusive_ptr info disk_io_thread io(ios); boost::shared_ptr dummy(new int); boost::intrusive_ptr pm = new piece_manager(dummy, info - , test_path, fp, io, default_storage_constructor); + , test_path, fp, io, default_storage_constructor, storage_mode); boost::mutex lock; - libtorrent::aux::piece_checker_data d; - std::vector pieces; - num_pieces = 0; - std::string error_msg; entry frd; - pm->verify_resume_data(frd, error_msg); - TEST_CHECK(pm->check_fastresume(d, pieces, num_pieces - , storage_mode, error_msg) == false); - bool finished = false; - float progress; - num_pieces = 0; - boost::recursive_mutex mutex; - bool error; - while (!finished) - boost::tie(finished, progress) = pm->check_files(pieces, num_pieces, mutex, error); - - TEST_CHECK(num_pieces == std::count(pieces.begin(), pieces.end() - , true)); + pm->async_check_fastresume(&frd, &on_check_resume_data); + test_sleep(2000); + pm->async_check_files(&on_check_files); + test_sleep(2000); boost::function none; TEST_CHECK(exists(test_path / "temp_storage"));