diff --git a/ChangeLog b/ChangeLog index 6ff5134f1..246c4b9b1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ + * added option to set file priorities when adding torrents * removed the session mutex for improved performance * added upload and download activity timer stats for torrents * made the reuse-address flag configurable on the listen socket diff --git a/docs/manual.rst b/docs/manual.rst index adf3365ee..f94fe9a0e 100644 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -369,12 +369,14 @@ add_torrent() :: typedef storage_interface* (&storage_constructor_type)( - file_storage const&, file_storage const*, fs::path const&, file_pool&); + file_storage const&, file_storage const*, fs::path const&, file_pool& + , std::vector const&); struct add_torrent_params { add_torrent_params(storage_constructor_type s); + int version; boost::intrusive_ptr ti; char const* tracker_url; sha1_hash info_hash; @@ -390,6 +392,7 @@ add_torrent() bool seed_mode; bool override_resume_data; bool upload_mode; + std::vector const* file_priorities; }; torrent_handle add_torrent(add_torrent_params const& params); @@ -500,6 +503,12 @@ on disk I/O errors, and if the torrent is also auto managed, it will be taken ou of this state periodically. This mode can be used to avoid race conditions when adjusting priorities of pieces before allowing the torrent to start downloading. +``file_priorities`` can be set to control the initial file priorities when adding +a torrent. The semantics are the same as for ``torrent_handle::prioritize_files()``. + +``version`` is filled in by the constructor and should be left untouched. It +is used for forward binary compatibility. + remove_torrent() ---------------- @@ -3749,6 +3758,7 @@ session_settings struct session_settings { session_settings(); + int version; std::string user_agent; int tracker_completion_timeout; int tracker_receive_timeout; @@ -3912,6 +3922,9 @@ session_settings int tick_interval; }; +``version`` is automatically set to the libtorrent version you're using +in order to be forward binary compatible. This field should not be changed. + ``user_agent`` this is the client identification to the tracker. The recommended format of this string is: "ClientName/ClientVersion libtorrent/libtorrentVersion". diff --git a/include/libtorrent/add_torrent_params.hpp b/include/libtorrent/add_torrent_params.hpp index fe7c6754e..add438104 100644 --- a/include/libtorrent/add_torrent_params.hpp +++ b/include/libtorrent/add_torrent_params.hpp @@ -39,6 +39,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/storage_defs.hpp" #include "libtorrent/peer_id.hpp" // sha1_hash +#include "libtorrent/version.hpp" namespace libtorrent { @@ -47,7 +48,8 @@ namespace libtorrent struct add_torrent_params { add_torrent_params(storage_constructor_type sc = default_storage_constructor) - : tracker_url(0) + : version(LIBTORRENT_VERSION_NUM) + , tracker_url(0) , name(0) , resume_data(0) , storage_mode(storage_mode_sparse) @@ -59,8 +61,11 @@ namespace libtorrent , seed_mode(false) , override_resume_data(false) , upload_mode(false) + , file_priorities(0) {} + // libtorrent version. Used for forward binary compatibility + int version; boost::intrusive_ptr ti; char const* tracker_url; sha1_hash info_hash; @@ -76,6 +81,7 @@ namespace libtorrent bool seed_mode; bool override_resume_data; bool upload_mode; + std::vector const* file_priorities; }; } diff --git a/include/libtorrent/create_torrent.hpp b/include/libtorrent/create_torrent.hpp index 6af990811..93c7e1655 100644 --- a/include/libtorrent/create_torrent.hpp +++ b/include/libtorrent/create_torrent.hpp @@ -255,7 +255,8 @@ namespace libtorrent { file_pool fp; boost::scoped_ptr st( - default_storage_constructor(const_cast(t.files()), 0, p, fp)); + default_storage_constructor(const_cast(t.files()), 0, p, fp + , std::vector())); // if we're calculating file hashes as well, use this hasher hasher filehash; @@ -354,7 +355,8 @@ namespace libtorrent std::string utf8; wchar_utf8(p, utf8); boost::scoped_ptr st( - default_storage_constructor(const_cast(t.files()), 0, utf8, fp)); + default_storage_constructor(const_cast(t.files()), 0, utf8, fp + , std::vector())); // calculate the hash for all pieces int num = t.num_pieces(); diff --git a/include/libtorrent/session_settings.hpp b/include/libtorrent/session_settings.hpp index 6fcf193b8..d59dfe34f 100644 --- a/include/libtorrent/session_settings.hpp +++ b/include/libtorrent/session_settings.hpp @@ -35,6 +35,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/version.hpp" #include "libtorrent/config.hpp" +#include "libtorrent/version.hpp" namespace libtorrent { @@ -84,7 +85,8 @@ namespace libtorrent { session_settings(std::string const& user_agent_ = "libtorrent/" LIBTORRENT_VERSION) - : user_agent(user_agent_) + : version(LIBTORRENT_VERSION_NUM) + , user_agent(user_agent_) , tracker_completion_timeout(60) , tracker_receive_timeout(40) , stop_tracker_timeout(5) @@ -216,6 +218,9 @@ namespace libtorrent , tick_interval(100) {} + // libtorrent version. Used for forward binary compatibility + int version; + // this is the user agent that will be sent to the tracker // when doing requests. It is used to identify the client. // It cannot contain \r or \n diff --git a/include/libtorrent/storage.hpp b/include/libtorrent/storage.hpp index 6054a8e40..2eb18ab81 100644 --- a/include/libtorrent/storage.hpp +++ b/include/libtorrent/storage.hpp @@ -199,7 +199,8 @@ namespace libtorrent , file_pool& fp , disk_io_thread& io , storage_constructor_type sc - , storage_mode_t sm); + , storage_mode_t sm + , std::vector const& file_prio); ~piece_manager(); diff --git a/include/libtorrent/storage_defs.hpp b/include/libtorrent/storage_defs.hpp index 0f6675f74..4d674a9cc 100644 --- a/include/libtorrent/storage_defs.hpp +++ b/include/libtorrent/storage_defs.hpp @@ -50,13 +50,13 @@ namespace libtorrent }; typedef storage_interface* (*storage_constructor_type)( - file_storage const&, file_storage const*, std::string const&, file_pool&); + file_storage const&, file_storage const*, std::string const&, file_pool&, std::vector const&); TORRENT_EXPORT storage_interface* default_storage_constructor( - file_storage const&, file_storage const* mapped, std::string const&, file_pool&); + file_storage const&, file_storage const* mapped, std::string const&, file_pool&, std::vector const&); TORRENT_EXPORT storage_interface* disabled_storage_constructor( - file_storage const&, file_storage const* mapped, std::string const&, file_pool&); + file_storage const&, file_storage const* mapped, std::string const&, file_pool&, std::vector const&); } diff --git a/include/libtorrent/version.hpp b/include/libtorrent/version.hpp index fcbf5f974..6e88df676 100644 --- a/include/libtorrent/version.hpp +++ b/include/libtorrent/version.hpp @@ -37,6 +37,10 @@ POSSIBILITY OF SUCH DAMAGE. #define LIBTORRENT_VERSION_MINOR 16 #define LIBTORRENT_VERSION_TINY 0 +// the format of this version is: MMmmtt +// M = Major version, m = minor version, t = tiny version +#define LIBTORRENT_VERSION_NUM ((LIBTORRENT_VERSION_MAJOR * 10000) + (LIBTORRENT_VERSION_MINOR * 100) + LIBTORRENT_VERSION_TINY) + #define LIBTORRENT_VERSION "0.16.0.0" #define LIBTORRENT_REVISION "$Rev$" diff --git a/src/storage.cpp b/src/storage.cpp index a7290f71c..6d5719bd6 100644 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -344,11 +344,13 @@ namespace libtorrent class storage : public storage_interface, boost::noncopyable { public: - storage(file_storage const& fs, file_storage const* mapped, std::string const& path, file_pool& fp) + storage(file_storage const& fs, file_storage const* mapped, std::string const& path + , file_pool& fp, std::vector const& file_prio) : m_files(fs) , m_pool(fp) , m_page_size(page_size()) , m_allocate_files(false) + , m_file_priority(file_prio) { if (mapped) m_mapped_files.reset(new file_storage(*mapped)); @@ -1318,9 +1320,10 @@ ret: } storage_interface* default_storage_constructor(file_storage const& fs - , file_storage const* mapped, std::string const& path, file_pool& fp) + , file_storage const* mapped, std::string const& path, file_pool& fp + , std::vector const& file_prio) { - return new storage(fs, mapped, path, fp); + return new storage(fs, mapped, path, fp, file_prio); } // this storage implementation does not write anything to disk @@ -1398,7 +1401,8 @@ ret: }; storage_interface* disabled_storage_constructor(file_storage const& fs - , file_storage const* mapped, std::string const& path, file_pool& fp) + , file_storage const* mapped, std::string const& path, file_pool& fp + , std::vector const&) { return new disabled_storage(fs.piece_length()); } @@ -1412,11 +1416,12 @@ ret: , file_pool& fp , disk_io_thread& io , storage_constructor_type sc - , storage_mode_t sm) + , storage_mode_t sm + , std::vector const& file_prio) : m_info(info) , m_files(m_info->files()) , m_storage(sc(m_info->orig_files(), &m_info->files() != &m_info->orig_files() - ? &m_info->files() : 0, save_path, fp)) + ? &m_info->files() : 0, save_path, fp, file_prio)) , m_storage_mode(sm) , m_save_path(complete(save_path)) , m_state(state_none) diff --git a/src/torrent.cpp b/src/torrent.cpp index ba110c4d5..4304689cf 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -382,6 +382,9 @@ namespace libtorrent , m_last_download(0) , m_last_upload(0) { + if (p.file_priorities) + m_file_priority = *p.file_priorities; + if (m_seed_mode) m_verified.resize(m_torrent_file->num_pieces(), false); @@ -841,7 +844,7 @@ namespace libtorrent // 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 - , (storage_mode_t)m_storage_mode); + , (storage_mode_t)m_storage_mode, m_file_priority); m_storage = m_owning_storage.get(); if (has_picker()) diff --git a/test/test_storage.cpp b/test/test_storage.cpp index 05f0e6c93..13b6f4324 100644 --- a/test/test_storage.cpp +++ b/test/test_storage.cpp @@ -222,7 +222,8 @@ private: }; storage_interface* create_test_storage(file_storage const& fs - , file_storage const* mapped, std::string const& path, file_pool& fp) + , file_storage const* mapped, std::string const& path, file_pool& fp + , std::vector const&) { return new test_storage; } @@ -280,7 +281,7 @@ void run_elevator_test() error_code ec; disk_io_thread dio(ios, &nop, fp); boost::intrusive_ptr pm(new piece_manager(boost::shared_ptr(), ti, "" - , fp, dio, &create_test_storage, storage_mode_sparse)); + , fp, dio, &create_test_storage, storage_mode_sparse, std::vector())); // we must disable the read cache in order to // verify that the elevator algorithm works. @@ -418,7 +419,7 @@ void run_storage_tests(boost::intrusive_ptr info file_pool fp; disk_buffer_pool dp(16 * 1024); boost::scoped_ptr s( - default_storage_constructor(fs, 0, test_path, fp)); + default_storage_constructor(fs, 0, test_path, fp, std::vector())); s->m_settings = &set; s->m_disk_pool = &dp; @@ -470,7 +471,7 @@ void run_storage_tests(boost::intrusive_ptr info disk_io_thread io(ios, boost::function(), fp); boost::shared_ptr dummy(new int); boost::intrusive_ptr pm = new piece_manager(dummy, info - , test_path, fp, io, default_storage_constructor, storage_mode); + , test_path, fp, io, default_storage_constructor, storage_mode, std::vector()); libtorrent::mutex lock; error_code ec; @@ -615,7 +616,7 @@ void test_remove(std::string const& test_path, bool unbuffered) file_pool fp; disk_buffer_pool dp(16 * 1024); boost::scoped_ptr s( - default_storage_constructor(fs, 0, test_path, fp)); + default_storage_constructor(fs, 0, test_path, fp, std::vector())); s->m_settings = &set; s->m_disk_pool = &dp; @@ -697,7 +698,7 @@ void test_check_files(std::string const& test_path disk_io_thread io(ios, boost::function(), fp); boost::shared_ptr dummy(new int); boost::intrusive_ptr pm = new piece_manager(dummy, info - , test_path, fp, io, default_storage_constructor, storage_mode); + , test_path, fp, io, default_storage_constructor, storage_mode, std::vector()); libtorrent::mutex lock; bool done = false; diff --git a/test/test_transfer.cpp b/test/test_transfer.cpp index aacfcda89..6afdf3083 100644 --- a/test/test_transfer.cpp +++ b/test/test_transfer.cpp @@ -121,7 +121,7 @@ void print_alert(std::auto_ptr) struct test_storage : storage_interface { test_storage(file_storage const& fs, std::string const& p, file_pool& fp) - : m_lower_layer(default_storage_constructor(fs, 0, p, fp)) + : m_lower_layer(default_storage_constructor(fs, 0, p, fp, std::vector())) , m_written(0) , m_limit(16 * 1024 * 2) {} @@ -213,7 +213,7 @@ struct test_storage : storage_interface }; storage_interface* test_storage_constructor(file_storage const& fs - , file_storage const*, std::string const& path, file_pool& fp) + , file_storage const*, std::string const& path, file_pool& fp, std::vector const&) { return new test_storage(fs, path, fp); }