diff --git a/TODO b/TODO index c65f792e8..358e93e1c 100644 --- a/TODO +++ b/TODO @@ -4,11 +4,11 @@ For 0.6 release: * Anonymous stats * Update checking * Translations -* Implement add by hash * Implement 'Classic' mode * Add progress bars for downloading and importing lists instead of hanging (blocklist) After 0.6 release: +* Implement add by hash * Figure out easy way for user-made plugins to add i18n support. * Restart daemon function * Docstrings! diff --git a/libtorrent/include/libtorrent/piece_picker.hpp b/libtorrent/include/libtorrent/piece_picker.hpp index 4b9e6bcc5..bd0f862b6 100755 --- a/libtorrent/include/libtorrent/piece_picker.hpp +++ b/libtorrent/include/libtorrent/piece_picker.hpp @@ -475,6 +475,10 @@ namespace libtorrent // if this is set to true, it means update_pieces() // has to be called before accessing m_pieces. mutable bool m_dirty; + public: + + enum { max_pieces = piece_pos::we_have_index - 1 }; + }; inline int piece_picker::blocks_in_piece(int index) const diff --git a/libtorrent/include/libtorrent/session.hpp b/libtorrent/include/libtorrent/session.hpp index ebd6b7ea5..fcae0be32 100755 --- a/libtorrent/include/libtorrent/session.hpp +++ b/libtorrent/include/libtorrent/session.hpp @@ -129,7 +129,7 @@ namespace libtorrent , resume_data(0) , storage_mode(storage_mode_sparse) , paused(true) - , auto_managed(false) + , auto_managed(true) , duplicate_is_error(false) , storage(sc) , userdata(0) diff --git a/libtorrent/include/libtorrent/torrent.hpp b/libtorrent/include/libtorrent/torrent.hpp index d08ee8b89..7f1e5f944 100755 --- a/libtorrent/include/libtorrent/torrent.hpp +++ b/libtorrent/include/libtorrent/torrent.hpp @@ -171,6 +171,8 @@ namespace libtorrent aux::session_impl& session() { return m_ses; } void set_sequential_download(bool sd); + bool is_sequential_download() const + { return m_sequential_download; } void set_queue_position(int p); int queue_position() const { return m_sequence_number; } diff --git a/libtorrent/include/libtorrent/torrent_handle.hpp b/libtorrent/include/libtorrent/torrent_handle.hpp index 636e842f0..25e9bbf21 100755 --- a/libtorrent/include/libtorrent/torrent_handle.hpp +++ b/libtorrent/include/libtorrent/torrent_handle.hpp @@ -429,6 +429,7 @@ namespace libtorrent int download_limit() const; void set_sequential_download(bool sd) const; + bool is_sequential_download() const; void set_peer_upload_limit(tcp::endpoint ip, int limit) const; void set_peer_download_limit(tcp::endpoint ip, int limit) const; diff --git a/libtorrent/src/policy.cpp b/libtorrent/src/policy.cpp index 20d38fdf4..d930ca6ff 100755 --- a/libtorrent/src/policy.cpp +++ b/libtorrent/src/policy.cpp @@ -635,11 +635,6 @@ namespace libtorrent return false; } - if (ec2) - { - i->second.connection->disconnect(ec2.message().c_str()); - } - if (self_connection) { c.disconnect("connected to ourselves", 1); @@ -650,7 +645,11 @@ namespace libtorrent TORRENT_ASSERT(i->second.connection != &c); // the new connection is a local (outgoing) connection // or the current one is already connected - if (!i->second.connection->is_connecting() || c.is_local()) + if (ec2) + { + i->second.connection->disconnect(ec2.message().c_str()); + } + else if (!i->second.connection->is_connecting() || c.is_local()) { c.disconnect("duplicate connection, closing"); return false; diff --git a/libtorrent/src/session_impl.cpp b/libtorrent/src/session_impl.cpp index e12075129..342c9bcd4 100755 --- a/libtorrent/src/session_impl.cpp +++ b/libtorrent/src/session_impl.cpp @@ -1357,13 +1357,15 @@ namespace aux { , end(downloaders.end()); i != end; ++i) { torrent* t = *i; - if (num_downloaders > 0 - && t->state() != torrent_status::queued_for_checking - && t->state() != torrent_status::checking_files) + if (num_downloaders > 0) { - --num_downloaders; - --num_seeds; - if (t->is_paused()) t->resume(); + if (t->state() != torrent_status::queued_for_checking + && t->state() != torrent_status::checking_files) + { + --num_downloaders; + --num_seeds; + if (t->is_paused()) t->resume(); + } } else { diff --git a/libtorrent/src/torrent.cpp b/libtorrent/src/torrent.cpp index 400f2c150..871e31c42 100755 --- a/libtorrent/src/torrent.cpp +++ b/libtorrent/src/torrent.cpp @@ -179,7 +179,7 @@ namespace libtorrent , m_max_uploads((std::numeric_limits::max)()) , m_num_uploads(0) , m_max_connections((std::numeric_limits::max)()) - , m_block_size(block_size) + , m_block_size((std::min)(block_size, tf->piece_length())) , m_complete(-1) , m_incomplete(-1) , m_deficit_counter(0) @@ -405,13 +405,22 @@ namespace libtorrent TORRENT_ASSERT(m_torrent_file->num_files() > 0); TORRENT_ASSERT(m_torrent_file->total_size() >= 0); + m_block_size = (std::min)(m_block_size, m_torrent_file->piece_length()); + + if (m_torrent_file->num_pieces() + > piece_picker::max_pieces) + { + m_error = "too many pieces in torrent"; + pause(); + } + // the shared_from_this() will create an intentional // cycle of ownership, se the hpp file for description. m_owning_storage = new piece_manager(shared_from_this(), m_torrent_file , m_save_path, m_ses.m_files, m_ses.m_disk_thread, m_storage_constructor , m_storage_mode); m_storage = m_owning_storage.get(); - m_picker->init(m_torrent_file->piece_length() / m_block_size + m_picker->init((std::max)(m_torrent_file->piece_length() / m_block_size, 1) , int((m_torrent_file->total_size()+m_block_size-1)/m_block_size)); std::vector const& url_seeds = m_torrent_file->url_seeds(); @@ -619,6 +628,10 @@ namespace libtorrent void torrent::force_recheck() { + if (m_state == torrent_status::checking_files + || m_state == torrent_status::queued_for_checking) + return; + disconnect_all(); m_owning_storage->async_release_files(); @@ -632,7 +645,9 @@ namespace libtorrent // assume that we don't have anything m_files_checked = false; m_state = torrent_status::queued_for_checking; - set_queue_position((std::numeric_limits::max)()); + + if (m_auto_managed) + set_queue_position((std::numeric_limits::max)()); m_resume_data = entry(); m_storage->async_check_fastresume(&m_resume_data @@ -3344,6 +3359,8 @@ namespace libtorrent TORRENT_ASSERT(total_done == m_torrent_file->total_size()); else TORRENT_ASSERT(total_done != m_torrent_file->total_size() || !m_files_checked); + + TORRENT_ASSERT(m_block_size <= m_torrent_file->piece_length()); } else { @@ -3394,7 +3411,9 @@ namespace libtorrent void torrent::set_queue_position(int p) { - TORRENT_ASSERT((p == -1) == is_finished()); + TORRENT_ASSERT((p == -1) == is_finished() + || (!m_auto_managed && p == -1) + || (m_abort && p == -1)); if (is_finished() && p != -1) return; if (p == m_sequence_number) return; diff --git a/libtorrent/src/torrent_handle.cpp b/libtorrent/src/torrent_handle.cpp index fe70c4b92..31e28e3a6 100755 --- a/libtorrent/src/torrent_handle.cpp +++ b/libtorrent/src/torrent_handle.cpp @@ -344,6 +344,12 @@ namespace libtorrent TORRENT_FORWARD(set_sequential_download(sd)); } + bool torrent_handle::is_sequential_download() const + { + INVARIANT_CHECK; + TORRENT_FORWARD_RETURN(is_sequential_download(), false); + } + std::string torrent_handle::name() const { INVARIANT_CHECK;