From 04589f3bef841f8a066e52645c476567d3845e1a Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Sun, 15 Jan 2017 01:21:52 -0500 Subject: [PATCH 1/7] don't load user_agent and peer_fingerprint from session_state (#1538) don't load user_agent and peer_fingerprint from session_state --- ChangeLog | 1 + include/libtorrent/session_handle.hpp | 5 +++ include/libtorrent/settings_pack.hpp | 5 +++ src/session_impl.cpp | 6 ++++ src/settings_pack.cpp | 36 +++++++++++++++++++++- test/test_session.cpp | 44 +++++++++++++++++++++++++++ test/test_settings_pack.cpp | 36 ++++++++++++++++++++++ 7 files changed, 132 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index bb8842beb..acbf8416a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ + * don't load user_agent and peer_fingerprint from session_state * fix file rename issue with name prefix matching torrent name * fix division by zero when setting tick_interval > 1000 * fix move_storage() to its own directory (would delete the files) diff --git a/include/libtorrent/session_handle.hpp b/include/libtorrent/session_handle.hpp index 03c225f14..c2c32d23e 100644 --- a/include/libtorrent/session_handle.hpp +++ b/include/libtorrent/session_handle.hpp @@ -119,6 +119,11 @@ namespace libtorrent // The ``flags`` argument is used to filter which parts of the session // state to save or load. By default, all state is saved/restored (except // for the individual torrents). see save_state_flags_t + // + // When saving settings, there are two fields that are *not* loaded. + // ``peer_fingerprint`` and ``user_agent``. Those are left as configured + // by the ``session_settings`` passed to the session constructor or + // subsequently set via apply_settings(). void save_state(entry& e, boost::uint32_t flags = 0xffffffff) const; void load_state(bdecode_node const& e, boost::uint32_t flags = 0xffffffff); diff --git a/include/libtorrent/settings_pack.hpp b/include/libtorrent/settings_pack.hpp index b1cc849d4..ee4e3d6a7 100644 --- a/include/libtorrent/settings_pack.hpp +++ b/include/libtorrent/settings_pack.hpp @@ -89,8 +89,13 @@ namespace libtorrent void set_int(int name, int val); void set_bool(int name, bool val); bool has_val(int name) const; + + // clear the settings pack from all settings void clear(); + // clear a specific setting from the pack + void clear(int name); + std::string get_str(int name) const; int get_int(int name) const; bool get_bool(int name) const; diff --git a/src/session_impl.cpp b/src/session_impl.cpp index d523baeb8..c1543974e 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -908,6 +908,12 @@ namespace aux { { // apply_settings_pack will update dht and proxy boost::shared_ptr pack = load_pack_from_dict(settings); + + // these settings are not loaded from state + // they are set by the client software, not configured by users + pack->clear(settings_pack::user_agent); + pack->clear(settings_pack::peer_fingerprint); + apply_settings_pack(pack); #ifndef TORRENT_DISABLE_DHT need_update_dht = false; diff --git a/src/settings_pack.cpp b/src/settings_pack.cpp index e2e7ecfc0..fc5b5a3b4 100644 --- a/src/settings_pack.cpp +++ b/src/settings_pack.cpp @@ -787,7 +787,7 @@ namespace libtorrent std::pair v(name, false); std::vector >::const_iterator i = std::lower_bound(m_bools.begin(), m_bools.end(), v - , &compare_first); + , &compare_first); if (i != m_bools.end() && i->first == name) return i->second; return false; } @@ -798,5 +798,39 @@ namespace libtorrent m_ints.clear(); m_bools.clear(); } + + void settings_pack::clear(int const name) + { + switch (name & type_mask) + { + case string_type_base: + { + std::pair v(name, std::string()); + std::vector >::iterator i + = std::lower_bound(m_strings.begin(), m_strings.end(), v + , &compare_first); + if (i != m_strings.end() && i->first == name) m_strings.erase(i); + break; + } + case int_type_base: + { + std::pair v(name, 0); + std::vector >::iterator i + = std::lower_bound(m_ints.begin(), m_ints.end(), v + , &compare_first); + if (i != m_ints.end() && i->first == name) m_ints.erase(i); + break; + } + case bool_type_base: + { + std::pair v(name, false); + std::vector >::iterator i + = std::lower_bound(m_bools.begin(), m_bools.end(), v + , &compare_first); + if (i != m_bools.end() && i->first == name) m_bools.erase(i); + break; + } + } + } } diff --git a/test/test_session.cpp b/test/test_session.cpp index 573eea1e4..b84f105b2 100644 --- a/test/test_session.cpp +++ b/test/test_session.cpp @@ -262,5 +262,49 @@ TORRENT_TEST(session_shutdown) lt::session ses(pack); } +// make sure we don't restore peer_id from session state +TORRENT_TEST(save_state_peer_id) +{ + lt::settings_pack pack; + pack.set_str(settings_pack::peer_fingerprint, "AAA"); + lt::session ses(pack); + lt::peer_id const pid1 = ses.id(); + TEST_CHECK(pid1[0] == 'A'); + TEST_CHECK(pid1[1] == 'A'); + TEST_CHECK(pid1[2] == 'A'); + + lt::entry st; + ses.save_state(st); + + pack.set_str(settings_pack::peer_fingerprint, "foobar"); + ses.apply_settings(pack); + + lt::peer_id const pid2 = ses.id(); + TEST_CHECK(pid2[0] == 'f'); + TEST_CHECK(pid2[1] == 'o'); + TEST_CHECK(pid2[2] == 'o'); + TEST_CHECK(pid2[3] == 'b'); + TEST_CHECK(pid2[4] == 'a'); + TEST_CHECK(pid2[5] == 'r'); + + + std::vector buf; + bencode(std::back_inserter(buf), st); + bdecode_node state; + error_code ec; + int ret = bdecode(buf.data(), buf.data() + buf.size() + , state, ec, nullptr, 100, 1000); + TEST_EQUAL(ret, 0); + ses.load_state(state); + + lt::peer_id const pid3 = ses.id(); + TEST_CHECK(pid3[0] == 'f'); + TEST_CHECK(pid3[1] == 'o'); + TEST_CHECK(pid3[2] == 'o'); + TEST_CHECK(pid3[3] == 'b'); + TEST_CHECK(pid3[4] == 'a'); + TEST_CHECK(pid3[5] == 'r'); +} + #endif diff --git a/test/test_settings_pack.cpp b/test/test_settings_pack.cpp index 5cebc9020..5e465c6e9 100644 --- a/test/test_settings_pack.cpp +++ b/test/test_settings_pack.cpp @@ -126,6 +126,42 @@ TORRENT_TEST(clear) TEST_EQUAL(pack.has_val(settings_pack::lazy_bitfields), false); } +TORRENT_TEST(clear_single_int) +{ + settings_pack sp; + sp.set_int(settings_pack::max_out_request_queue, 1337); + + TEST_EQUAL(sp.get_int(settings_pack::max_out_request_queue), 1337); + + sp.clear(settings_pack::max_out_request_queue); + + TEST_EQUAL(sp.get_int(settings_pack::max_out_request_queue), 0); +} + +TORRENT_TEST(clear_single_bool) +{ + settings_pack sp; + sp.set_bool(settings_pack::send_redundant_have, true); + + TEST_EQUAL(sp.get_bool(settings_pack::send_redundant_have), true); + + sp.clear(settings_pack::send_redundant_have); + + TEST_EQUAL(sp.get_bool(settings_pack::send_redundant_have), false); +} + +TORRENT_TEST(clear_single_string) +{ + settings_pack sp; + sp.set_str(settings_pack::user_agent, "foobar"); + + TEST_EQUAL(sp.get_str(settings_pack::user_agent), "foobar"); + + sp.clear(settings_pack::user_agent); + + TEST_EQUAL(sp.get_str(settings_pack::user_agent), std::string()); +} + TORRENT_TEST(duplicates) { settings_pack p; From 27001750a442c261b4283bbfb10eca9f58e51ffd Mon Sep 17 00:00:00 2001 From: arvidn Date: Sun, 15 Jan 2017 13:46:08 -0500 Subject: [PATCH 2/7] add python binding for generate_fingerprint --- bindings/python/src/fingerprint.cpp | 2 ++ bindings/python/test.py | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/bindings/python/src/fingerprint.cpp b/bindings/python/src/fingerprint.cpp index b079ef3c5..1721abf17 100644 --- a/bindings/python/src/fingerprint.cpp +++ b/bindings/python/src/fingerprint.cpp @@ -10,6 +10,8 @@ void bind_fingerprint() using namespace boost::python; using namespace libtorrent; + def("generate_fingerprint", &generate_fingerprint); + #ifndef TORRENT_NO_DEPRECATE class_("fingerprint", no_init) .def( diff --git a/bindings/python/test.py b/bindings/python/test.py index 8aa6390c2..0dce7dfcd 100644 --- a/bindings/python/test.py +++ b/bindings/python/test.py @@ -230,6 +230,10 @@ class test_session(unittest.TestCase): except KeyError as e: print(e) + def test_fingerprint(self): + self.assertEqual(lt.generate_fingerprint('LT', 0, 1, 2, 3), '-LT0123-') + self.assertEqual(lt.generate_fingerprint('..', 10, 1, 2, 3), '-..A123-') + def test_deprecated_settings(self): # this detects whether libtorrent was built with deprecated APIs From 3b9c65daf1bcd898929b2b9243e621c7b242f13d Mon Sep 17 00:00:00 2001 From: arvidn Date: Mon, 16 Jan 2017 09:40:51 -0500 Subject: [PATCH 3/7] remove unused function, has_interface() --- include/libtorrent/enum_net.hpp | 4 ---- src/enum_net.cpp | 11 ----------- 2 files changed, 15 deletions(-) diff --git a/include/libtorrent/enum_net.hpp b/include/libtorrent/enum_net.hpp index c82c8e187..866d255e1 100644 --- a/include/libtorrent/enum_net.hpp +++ b/include/libtorrent/enum_net.hpp @@ -179,10 +179,6 @@ namespace libtorrent return bind_ep.address(); } - // returns true if the given device exists - TORRENT_EXTRA_EXPORT bool has_interface(char const* name, io_service& ios - , error_code& ec); - // returns the device name whose local address is ``addr``. If // no such device is found, an empty string is returned. TORRENT_EXTRA_EXPORT std::string device_for_address(address addr diff --git a/src/enum_net.cpp b/src/enum_net.cpp index a9cdca5f3..796763776 100644 --- a/src/enum_net.cpp +++ b/src/enum_net.cpp @@ -1138,17 +1138,6 @@ namespace libtorrent return ret; } - // returns true if the given device exists - bool has_interface(char const* name, io_service& ios, error_code& ec) - { - std::vector ifs = enum_net_interfaces(ios, ec); - if (ec) return false; - - for (int i = 0; i < int(ifs.size()); ++i) - if (ifs[i].name == name) return true; - return false; - } - // returns the device name whose local address is ``addr``. If // no such device is found, an empty string is returned. std::string device_for_address(address addr, io_service& ios, error_code& ec) From a07ffe42f85f1fed68cb1ecbde9e4ee5b2c0ea78 Mon Sep 17 00:00:00 2001 From: Falcosc Date: Tue, 17 Jan 2017 00:20:43 +0100 Subject: [PATCH 4/7] fix torrent peer class index overflow (#1557) fix peer class index width --- ChangeLog | 1 + include/libtorrent/peer_class.hpp | 2 +- src/peer_class.cpp | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index acbf8416a..b3393ea0c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ + * fix per-torrent rate limits for >256 peer classes * don't load user_agent and peer_fingerprint from session_state * fix file rename issue with name prefix matching torrent name * fix division by zero when setting tick_interval > 1000 diff --git a/include/libtorrent/peer_class.hpp b/include/libtorrent/peer_class.hpp index a7bc61cc1..f11f412b0 100644 --- a/include/libtorrent/peer_class.hpp +++ b/include/libtorrent/peer_class.hpp @@ -47,7 +47,7 @@ POSSIBILITY OF SUCH DAMAGE. namespace libtorrent { - typedef boost::uint8_t peer_class_t; + typedef boost::uint32_t peer_class_t; struct peer_class_info { diff --git a/src/peer_class.cpp b/src/peer_class.cpp index 9a1dd9f7d..945ab641a 100644 --- a/src/peer_class.cpp +++ b/src/peer_class.cpp @@ -87,6 +87,7 @@ namespace libtorrent } else { + TORRENT_ASSERT(m_peer_classes.size() < 0x100000000); ret = m_peer_classes.size(); m_peer_classes.push_back(boost::shared_ptr()); } From c7c204280ad65b544449354bf15f35e3be3941e3 Mon Sep 17 00:00:00 2001 From: arvidn Date: Wed, 18 Jan 2017 20:13:46 -0500 Subject: [PATCH 5/7] make sure torrent_info::is_valid returns false when the file fails to load --- ChangeLog | 1 + src/create_torrent.cpp | 2 ++ src/torrent_info.cpp | 18 ++++++++++++++++++ test/test_torrent_info.cpp | 1 + 4 files changed, 22 insertions(+) diff --git a/ChangeLog b/ChangeLog index b3393ea0c..c0cee8678 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ + * make torrent_info::is_valid() return false if torrent failed to load * fix per-torrent rate limits for >256 peer classes * don't load user_agent and peer_fingerprint from session_state * fix file rename issue with name prefix matching torrent name diff --git a/src/create_torrent.cpp b/src/create_torrent.cpp index 78d2b67f7..5f2e66a56 100644 --- a/src/create_torrent.cpp +++ b/src/create_torrent.cpp @@ -388,6 +388,8 @@ namespace libtorrent TORRENT_ASSERT(ti.num_files() > 0); TORRENT_ASSERT(ti.total_size() > 0); + if (!ti.is_valid()) return; + if (ti.creation_date()) m_creation_date = *ti.creation_date(); if (!ti.creator().empty()) set_creator(ti.creator().c_str()); diff --git a/src/torrent_info.cpp b/src/torrent_info.cpp index 04508c259..8dc50188b 100644 --- a/src/torrent_info.cpp +++ b/src/torrent_info.cpp @@ -1249,6 +1249,8 @@ namespace libtorrent if (!name_ent) { ec = errors::torrent_missing_name; + // mark the torrent as invalid + m_files.set_piece_length(0); return false; } @@ -1266,14 +1268,22 @@ namespace libtorrent // this is the counter used to name pad files int pad_file_cnt = 0; if (!extract_single_file(info, files, "", info_ptr_diff, true, pad_file_cnt, ec)) + { + // mark the torrent as invalid + m_files.set_piece_length(0); return false; + } m_multifile = false; } else { if (!extract_files(files_node, files, name, info_ptr_diff, ec)) + { + // mark the torrent as invalid + m_files.set_piece_length(0); return false; + } m_multifile = true; } TORRENT_ASSERT(!files.name().empty()); @@ -1290,6 +1300,8 @@ namespace libtorrent if (!pieces && !root_hash) { ec = errors::torrent_missing_pieces; + // mark the torrent as invalid + m_files.set_piece_length(0); return false; } @@ -1298,6 +1310,8 @@ namespace libtorrent if (pieces.string_length() != files.num_pieces() * 20) { ec = errors::torrent_invalid_hashes; + // mark the torrent as invalid + m_files.set_piece_length(0); return false; } @@ -1311,6 +1325,8 @@ namespace libtorrent if (root_hash.string_length() != 20) { ec = errors::torrent_invalid_hashes; + // mark the torrent as invalid + m_files.set_piece_length(0); return false; } int num_leafs = merkle_num_leafs(files.num_pieces()); @@ -1318,6 +1334,8 @@ namespace libtorrent if (num_nodes - num_leafs >= (2<<24)) { ec = errors::too_many_pieces_in_torrent; + // mark the torrent as invalid + m_files.set_piece_length(0); return false; } m_merkle_first_leaf = num_nodes - num_leafs; diff --git a/test/test_torrent_info.cpp b/test/test_torrent_info.cpp index d0a0301cc..e2f80782c 100644 --- a/test/test_torrent_info.cpp +++ b/test/test_torrent_info.cpp @@ -775,6 +775,7 @@ TORRENT_TEST(parse_torrents) fprintf(stdout, "E: \"%s\"\nexpected: \"%s\"\n", ec.message().c_str() , test_error_torrents[i].error.message().c_str()); TEST_CHECK(ec.message() == test_error_torrents[i].error.message()); + TEST_EQUAL(ti->is_valid(), false); } } From c57d062e0d731da73ff648af59da47e2dc059cad Mon Sep 17 00:00:00 2001 From: Falco Date: Fri, 20 Jan 2017 15:56:22 +0000 Subject: [PATCH 6/7] fix torrent name in alerts of builds with deprecated functions and use non deprecated for internal calls --- ChangeLog | 1 + src/alert.cpp | 50 +------------------------------------------------- 2 files changed, 2 insertions(+), 49 deletions(-) diff --git a/ChangeLog b/ChangeLog index c0cee8678..12fc85240 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ + * fix torrent name in alerts of builds with deprecated functions * make torrent_info::is_valid() return false if torrent failed to load * fix per-torrent rate limits for >256 peer classes * don't load user_agent and peer_fingerprint from session_state diff --git a/src/alert.cpp b/src/alert.cpp index 6db3bce69..8e8d2007b 100644 --- a/src/alert.cpp +++ b/src/alert.cpp @@ -81,17 +81,13 @@ namespace libtorrent { } #ifndef TORRENT_NO_DEPRECATE - name = torrent_name(); + name = m_alloc.ptr(m_name_idx); #endif } char const* torrent_alert::torrent_name() const { -#ifndef TORRENT_NO_DEPRECATE - return name.c_str(); -#else return m_alloc.ptr(m_name_idx); -#endif } std::string torrent_alert::message() const @@ -128,11 +124,7 @@ namespace libtorrent { char const* tracker_alert::tracker_url() const { -#ifndef TORRENT_NO_DEPRECATE - return url.c_str(); -#else return m_alloc.ptr(m_url_idx); -#endif } std::string tracker_alert::message() const @@ -203,11 +195,7 @@ namespace libtorrent { char const* file_renamed_alert::new_name() const { -#ifndef TORRENT_NO_DEPRECATE - return name.c_str(); -#else return m_alloc.ptr(m_name_idx); -#endif } std::string file_renamed_alert::message() const @@ -304,11 +292,7 @@ namespace libtorrent { char const* tracker_error_alert::error_message() const { -#ifndef TORRENT_NO_DEPRECATE - return msg.c_str(); -#else return m_alloc.ptr(m_msg_idx); -#endif } std::string tracker_error_alert::message() const @@ -336,11 +320,7 @@ namespace libtorrent { char const* tracker_warning_alert::warning_message() const { -#ifndef TORRENT_NO_DEPRECATE - return msg.c_str(); -#else return m_alloc.ptr(m_msg_idx); -#endif } std::string tracker_warning_alert::message() const @@ -398,12 +378,8 @@ namespace libtorrent { char const* scrape_failed_alert::error_message() const { -#ifndef TORRENT_NO_DEPRECATE - return msg.c_str(); -#else if (m_msg_idx == -1) return ""; else return m_alloc.ptr(m_msg_idx); -#endif } std::string scrape_failed_alert::message() const @@ -673,11 +649,7 @@ namespace libtorrent { char const* storage_moved_alert::storage_path() const { -#ifndef TORRENT_NO_DEPRECATE - return path.c_str(); -#else return m_alloc.ptr(m_path_idx); -#endif } storage_moved_failed_alert::storage_moved_failed_alert( @@ -697,11 +669,7 @@ namespace libtorrent { char const* storage_moved_failed_alert::file_path() const { -#ifndef TORRENT_NO_DEPRECATE - return file.c_str(); -#else return m_alloc.ptr(m_file_idx); -#endif } std::string storage_moved_failed_alert::message() const @@ -972,11 +940,7 @@ namespace libtorrent { char const* portmap_log_alert::log_message() const { -#ifndef TORRENT_NO_DEPRECATE - return msg.c_str(); -#else return m_alloc.ptr(m_log_idx); -#endif } std::string portmap_log_alert::message() const @@ -1017,11 +981,7 @@ namespace libtorrent { char const* fastresume_rejected_alert::file_path() const { -#ifndef TORRENT_NO_DEPRECATE - return file.c_str(); -#else return m_alloc.ptr(m_path_idx); -#endif } peer_blocked_alert::peer_blocked_alert(aux::stack_allocator& alloc @@ -1186,11 +1146,7 @@ namespace libtorrent { char const* trackerid_alert::tracker_id() const { -#ifndef TORRENT_NO_DEPRECATE - return trackerid.c_str(); -#else return m_alloc.ptr(m_tracker_idx); -#endif } std::string trackerid_alert::message() const @@ -1762,12 +1718,8 @@ namespace libtorrent { char const* url_seed_alert::error_message() const { -#ifndef TORRENT_NO_DEPRECATE - return msg.c_str(); -#else if (m_msg_idx == -1) return ""; return m_alloc.ptr(m_msg_idx); -#endif } file_error_alert::file_error_alert(aux::stack_allocator& alloc From 6d17f0fb662fc3d86b950caf2e0e469e75a25a49 Mon Sep 17 00:00:00 2001 From: arvidn Date: Fri, 20 Jan 2017 23:30:05 -0500 Subject: [PATCH 7/7] storage optimization to peer classes --- ChangeLog | 1 + include/libtorrent/peer_class.hpp | 19 ++++++++++++++----- src/peer_class.cpp | 26 +++++++++++++------------- test/test_peer_classes.cpp | 10 +++++----- 4 files changed, 33 insertions(+), 23 deletions(-) diff --git a/ChangeLog b/ChangeLog index 12fc85240..dea188316 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ + * storage optimization to peer classes * fix torrent name in alerts of builds with deprecated functions * make torrent_info::is_valid() return false if torrent failed to load * fix per-torrent rate limits for >256 peer classes diff --git a/include/libtorrent/peer_class.hpp b/include/libtorrent/peer_class.hpp index f11f412b0..3c278ccb1 100644 --- a/include/libtorrent/peer_class.hpp +++ b/include/libtorrent/peer_class.hpp @@ -39,8 +39,8 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/aux_/disable_warnings_push.hpp" #include +#include #include -#include #include #include "libtorrent/aux_/disable_warnings_pop.hpp" @@ -86,12 +86,13 @@ namespace libtorrent int download_priority; }; - struct TORRENT_EXTRA_EXPORT peer_class : boost::enable_shared_from_this + struct TORRENT_EXTRA_EXPORT peer_class { friend struct peer_class_pool; peer_class(std::string const& l) - : ignore_unchoke_slots(false) + : in_use(true) + , ignore_unchoke_slots(false) , connection_limit_factor(100) , label(l) , references(1) @@ -100,6 +101,12 @@ namespace libtorrent priority[1] = 1; } + void clear() + { + in_use = false; + label.clear(); + } + void set_info(peer_class_info const* pci); void get_info(peer_class_info* pci) const; @@ -110,6 +117,9 @@ namespace libtorrent // keeps track of the current quotas bandwidth_channel channel[2]; + // this is set to false when this slot is not in use for a peer_class + bool in_use; + bool ignore_unchoke_slots; int connection_limit_factor; @@ -123,7 +133,6 @@ namespace libtorrent private: int references; - }; struct TORRENT_EXTRA_EXPORT peer_class_pool @@ -138,7 +147,7 @@ namespace libtorrent // state for peer classes (a peer can belong to multiple classes) // this can control - std::vector > m_peer_classes; + std::deque m_peer_classes; // indices in m_peer_classes that are no longer used std::vector m_free_list; diff --git a/src/peer_class.cpp b/src/peer_class.cpp index 945ab641a..ea1979920 100644 --- a/src/peer_class.cpp +++ b/src/peer_class.cpp @@ -84,16 +84,15 @@ namespace libtorrent { ret = m_free_list.back(); m_free_list.pop_back(); + m_peer_classes[ret] = peer_class(label); } else { TORRENT_ASSERT(m_peer_classes.size() < 0x100000000); ret = m_peer_classes.size(); - m_peer_classes.push_back(boost::shared_ptr()); + m_peer_classes.push_back(peer_class(label)); } - TORRENT_ASSERT(m_peer_classes[ret].get() == 0); - m_peer_classes[ret] = boost::make_shared(label); return ret; } @@ -103,11 +102,12 @@ namespace libtorrent VALGRIND_CHECK_VALUE_IS_DEFINED(c); #endif TORRENT_ASSERT(c < m_peer_classes.size()); - TORRENT_ASSERT(m_peer_classes[c].get()); + TORRENT_ASSERT(m_peer_classes[c].in_use); + TORRENT_ASSERT(m_peer_classes[c].references > 0); - --m_peer_classes[c]->references; - if (m_peer_classes[c]->references) return; - m_peer_classes[c].reset(); + --m_peer_classes[c].references; + if (m_peer_classes[c].references) return; + m_peer_classes[c].clear(); m_free_list.push_back(c); } @@ -117,9 +117,9 @@ namespace libtorrent VALGRIND_CHECK_VALUE_IS_DEFINED(c); #endif TORRENT_ASSERT(c < m_peer_classes.size()); - TORRENT_ASSERT(m_peer_classes[c].get()); + TORRENT_ASSERT(m_peer_classes[c].in_use); - ++m_peer_classes[c]->references; + ++m_peer_classes[c].references; } peer_class* peer_class_pool::at(peer_class_t c) @@ -127,14 +127,14 @@ namespace libtorrent #ifdef TORRENT_USE_VALGRIND VALGRIND_CHECK_VALUE_IS_DEFINED(c); #endif - if (c >= m_peer_classes.size()) return 0; - return m_peer_classes[c].get(); + if (c >= m_peer_classes.size() || !m_peer_classes[c].in_use) return NULL; + return &m_peer_classes[c]; } peer_class const* peer_class_pool::at(peer_class_t c) const { - if (c >= m_peer_classes.size()) return 0; - return m_peer_classes[c].get(); + if (c >= m_peer_classes.size() || !m_peer_classes[c].in_use) return NULL; + return &m_peer_classes[c]; } } diff --git a/test/test_peer_classes.cpp b/test/test_peer_classes.cpp index d81d3ec84..541af1766 100644 --- a/test/test_peer_classes.cpp +++ b/test/test_peer_classes.cpp @@ -66,11 +66,11 @@ TORRENT_TEST(peer_class) TEST_CHECK(id3 == id2 + 1); // make sure refcounting works - TEST_CHECK(class_name(id3, pool) == "test3"); + TEST_EQUAL(class_name(id3, pool), "test3"); pool.incref(id3); - TEST_CHECK(class_name(id3, pool) == "test3"); + TEST_EQUAL(class_name(id3, pool), "test3"); pool.decref(id3); - TEST_CHECK(class_name(id3, pool) == "test3"); + TEST_EQUAL(class_name(id3, pool), "test3"); pool.decref(id3); // it should have been deleted now TEST_CHECK(pool.at(id3) == NULL); @@ -81,8 +81,8 @@ TORRENT_TEST(peer_class) peer_class_info i; pool.at(id2)->get_info(&i); - TEST_CHECK(i.upload_limit == 1000); - TEST_CHECK(i.download_limit == 2000); + TEST_EQUAL(i.upload_limit, 1000); + TEST_EQUAL(i.download_limit, 2000); // test peer_class_type_filter peer_class_type_filter filter;