From 6a701437b60d38255bb3c05cb263cd575c31a7e5 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Sat, 21 Jan 2017 22:40:19 -0500 Subject: [PATCH] use strong_typedef for peer_class_t type (#1595) use strong_typedef for peer_class_t type --- ChangeLog | 4 +- include/libtorrent/Makefile.am | 1 + include/libtorrent/aux_/deque.hpp | 119 ++++++++++++++++++ include/libtorrent/aux_/range.hpp | 64 ++++++++++ include/libtorrent/aux_/session_impl.hpp | 8 +- include/libtorrent/aux_/vector.hpp | 30 ----- include/libtorrent/peer_class.hpp | 34 ++--- include/libtorrent/peer_class_type_filter.hpp | 44 ++++--- include/libtorrent/session_handle.hpp | 23 ++-- include/libtorrent/torrent.hpp | 4 +- include/libtorrent/units.hpp | 12 +- src/peer_class.cpp | 19 ++- src/piece_picker.cpp | 1 + src/session_handle.cpp | 9 +- src/session_impl.cpp | 8 +- src/torrent.cpp | 14 +-- test/setup_transfer.cpp | 2 +- test/test_peer_classes.cpp | 10 +- 18 files changed, 296 insertions(+), 110 deletions(-) create mode 100644 include/libtorrent/aux_/deque.hpp create mode 100644 include/libtorrent/aux_/range.hpp diff --git a/ChangeLog b/ChangeLog index 374ce19a7..abf4b8378 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,6 @@ - * fix crash caused by empty bitfield + * introduce introduce distinct types for peer_class_t, piece_index_t and + file_index_t. + * fix crash caused by empty bitfield * removed disk-access-log build configuration * removed mmap_cache feature * strengthened type safety in handling of piece and file indices diff --git a/include/libtorrent/Makefile.am b/include/libtorrent/Makefile.am index aad56caa4..a95115d8e 100644 --- a/include/libtorrent/Makefile.am +++ b/include/libtorrent/Makefile.am @@ -164,6 +164,7 @@ nobase_include_HEADERS = \ aux_/disable_warnings_push.hpp \ aux_/disable_warnings_pop.hpp \ aux_/dev_random.hpp \ + aux_/deque.hpp \ aux_/escape_string.hpp \ aux_/io.hpp \ aux_/max_path.hpp \ diff --git a/include/libtorrent/aux_/deque.hpp b/include/libtorrent/aux_/deque.hpp new file mode 100644 index 000000000..7cd5d213a --- /dev/null +++ b/include/libtorrent/aux_/deque.hpp @@ -0,0 +1,119 @@ +/* + +Copyright (c) 2017, Arvid Norberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + * Neither the name of the author nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef TORRENT_DEQUE_HPP +#define TORRENT_DEQUE_HPP + +#include +#include + +#include "libtorrent/units.hpp" +#include "libtorrent/assert.hpp" + +namespace libtorrent { namespace aux { + + template + struct deque : std::deque + { + using base = std::deque; + using underlying_index = typename underlying_index_t::type; + + // pull in constructors from base class + using base::base; + + auto operator[](IndexType idx) const -> decltype(this->base::operator[](underlying_index())) + { + TORRENT_ASSERT(idx >= IndexType(0)); + TORRENT_ASSERT(idx < end_index()); + return this->base::operator[](std::size_t(static_cast(idx))); + } + + auto operator[](IndexType idx) -> decltype(this->base::operator[](underlying_index())) + { + TORRENT_ASSERT(idx >= IndexType(0)); + TORRENT_ASSERT(idx < end_index()); + return this->base::operator[](std::size_t(static_cast(idx))); + } + + IndexType end_index() const + { + TORRENT_ASSERT(this->size() <= std::size_t(std::numeric_limits::max())); + return IndexType(static_cast(this->size())); + } + + template ::value>::type> + void resize(underlying_index s) + { + TORRENT_ASSERT(s >= 0); + this->base::resize(std::size_t(s)); + } + + template ::value>::type> + void resize(underlying_index s, T const& v) + { + TORRENT_ASSERT(s >= 0); + this->base::resize(std::size_t(s), v); + } + + void resize(std::size_t s) + { + TORRENT_ASSERT(s <= std::size_t((std::numeric_limits::max)())); + this->base::resize(s); + } + + void resize(std::size_t s, T const& v) + { + TORRENT_ASSERT(s <= std::size_t((std::numeric_limits::max)())); + this->base::resize(s, v); + } + + template ::value>::type> + void reserve(underlying_index s) + { + TORRENT_ASSERT(s >= 0); + this->base::reserve(std::size_t(s)); + } + + void reserve(std::size_t s) + { + TORRENT_ASSERT(s <= std::size_t((std::numeric_limits::max)())); + this->base::reserve(s); + } + }; + +}} + +#endif + diff --git a/include/libtorrent/aux_/range.hpp b/include/libtorrent/aux_/range.hpp new file mode 100644 index 000000000..5ca677b69 --- /dev/null +++ b/include/libtorrent/aux_/range.hpp @@ -0,0 +1,64 @@ +/* + +Copyright (c) 2016, Arvid Norberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + * Neither the name of the author nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef TORRENT_RANGE_HPP +#define TORRENT_RANGE_HPP + +namespace libtorrent { namespace aux { + + template + struct iterator_range + { + Iter _begin, _end; + Iter begin() { return _begin; } + Iter end() { return _end; } + }; + + template + iterator_range range(vector& vec + , IndexType begin, IndexType end) + { + using type = typename underlying_index_t::type; + return {vec.data() + static_cast(begin), vec.data() + static_cast(end)}; + } + + template + iterator_range range(vector const& vec + , IndexType begin, IndexType end) + { + using type = typename underlying_index_t::type; + return {vec.data() + static_cast(begin), vec.data() + static_cast(end)}; + } +}} + +#endif + diff --git a/include/libtorrent/aux_/session_impl.hpp b/include/libtorrent/aux_/session_impl.hpp index 40391c05e..7894e1c67 100644 --- a/include/libtorrent/aux_/session_impl.hpp +++ b/include/libtorrent/aux_/session_impl.hpp @@ -453,7 +453,7 @@ namespace libtorrent int use_quota_overhead(peer_class_set& set, int amount_down, int amount_up) override; bool use_quota_overhead(bandwidth_channel* ch, int amount); - int create_peer_class(char const* name); + peer_class_t create_peer_class(char const* name); void delete_peer_class(int cid); void set_peer_class_filter(ip_filter const& f); ip_filter const& get_peer_class_filter() const; @@ -796,7 +796,7 @@ namespace libtorrent bandwidth_manager m_upload_rate; // the peer class that all peers belong to by default - peer_class_t m_global_class = 0; + peer_class_t m_global_class{0}; // the peer class all TCP peers belong to by default // all tcp peer connections are subject to these @@ -805,10 +805,10 @@ namespace libtorrent // throttle TCP that passes over the internet // bottleneck (i.e. modem) to avoid starving out // uTP connections. - peer_class_t m_tcp_peer_class = 0; + peer_class_t m_tcp_peer_class{0}; // peer class for local peers - peer_class_t m_local_peer_class = 0; + peer_class_t m_local_peer_class{0}; tracker_manager m_tracker_manager; torrent_map m_torrents; diff --git a/include/libtorrent/aux_/vector.hpp b/include/libtorrent/aux_/vector.hpp index 9ffcd0d00..6d706faa4 100644 --- a/include/libtorrent/aux_/vector.hpp +++ b/include/libtorrent/aux_/vector.hpp @@ -41,12 +41,6 @@ POSSIBILITY OF SUCH DAMAGE. namespace libtorrent { namespace aux { - template - struct underlying_index_t { using type = T; }; - - template - struct underlying_index_t> { using type = U; }; - template struct vector : std::vector { @@ -119,30 +113,6 @@ namespace libtorrent { namespace aux { } }; - template - struct iterator_range - { - Iter _begin, _end; - Iter begin() { return _begin; } - Iter end() { return _end; } - }; - - template - iterator_range range(vector& vec - , IndexType begin, IndexType end) - { - using type = typename underlying_index_t::type; - return {vec.data() + static_cast(begin), vec.data() + static_cast(end)}; - } - - template - iterator_range range(vector const& vec - , IndexType begin, IndexType end) - { - using type = typename underlying_index_t::type; - return {vec.data() + static_cast(begin), vec.data() + static_cast(end)}; - } - // TODO: find a better place for this function template ::value && std::is_integral::value>::type> diff --git a/include/libtorrent/peer_class.hpp b/include/libtorrent/peer_class.hpp index 9842e78a9..73914a038 100644 --- a/include/libtorrent/peer_class.hpp +++ b/include/libtorrent/peer_class.hpp @@ -33,18 +33,24 @@ POSSIBILITY OF SUCH DAMAGE. #ifndef TORRENT_PEER_CLASS_HPP_INCLUDED #define TORRENT_PEER_CLASS_HPP_INCLUDED -#include "libtorrent/bandwidth_limit.hpp" +#include "libtorrent/config.hpp" #include "libtorrent/assert.hpp" +#include "libtorrent/bandwidth_limit.hpp" +#include "libtorrent/units.hpp" +#include "libtorrent/aux_/deque.hpp" #include -#include #include #include #include -namespace libtorrent -{ - typedef std::uint32_t peer_class_t; +namespace libtorrent { + + namespace aux { + struct peer_class_tag; + } + + using peer_class_t = aux::strong_typedef; struct peer_class_info { @@ -87,11 +93,11 @@ namespace libtorrent { friend struct peer_class_pool; - explicit peer_class(std::string const& l) - : in_use(true) - , ignore_unchoke_slots(false) + explicit peer_class(std::string l) + : ignore_unchoke_slots(false) , connection_limit_factor(100) - , label(l) + , label(std::move(l)) + , in_use(true) , references(1) { priority[0] = 1; @@ -114,9 +120,6 @@ 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; @@ -129,12 +132,15 @@ namespace libtorrent std::string label; private: + // this is set to false when this slot is not in use for a peer_class + bool in_use; + int references; }; struct TORRENT_EXTRA_EXPORT peer_class_pool { - peer_class_t new_peer_class(std::string const& label); + peer_class_t new_peer_class(std::string label); void decref(peer_class_t c); void incref(peer_class_t c); peer_class* at(peer_class_t c); @@ -144,7 +150,7 @@ namespace libtorrent // state for peer classes (a peer can belong to multiple classes) // this can control - std::deque m_peer_classes; + aux::deque m_peer_classes; // indices in m_peer_classes that are no longer used std::vector m_free_list; diff --git a/include/libtorrent/peer_class_type_filter.hpp b/include/libtorrent/peer_class_type_filter.hpp index e6b737e3d..61f6f0a3a 100644 --- a/include/libtorrent/peer_class_type_filter.hpp +++ b/include/libtorrent/peer_class_type_filter.hpp @@ -65,25 +65,27 @@ namespace libtorrent // ``add()`` and ``remove()`` adds and removes a peer class to be added // to new peers based on socket type. - void add(socket_type_t st, int peer_class) + void add(socket_type_t st, peer_class_t const peer_class) { - TORRENT_ASSERT(peer_class >= 0); - TORRENT_ASSERT(peer_class < 32); - if (peer_class < 0 || peer_class > 31) return; + TORRENT_ASSERT(peer_class >= peer_class_t{0}); + TORRENT_ASSERT(peer_class < peer_class_t{32}); + if (peer_class < peer_class_t{0} + || peer_class > peer_class_t{31}) return; TORRENT_ASSERT(st < num_socket_types && st >= 0); if (st < 0 || st >= num_socket_types) return; - m_peer_class_type[st] |= 1 << peer_class; + m_peer_class_type[st] |= 1 << static_cast(peer_class); } - void remove(socket_type_t st, int peer_class) + void remove(socket_type_t st, peer_class_t const peer_class) { - TORRENT_ASSERT(peer_class >= 0); - TORRENT_ASSERT(peer_class < 32); - if (peer_class < 0 || peer_class > 31) return; + TORRENT_ASSERT(peer_class >= peer_class_t{0}); + TORRENT_ASSERT(peer_class < peer_class_t{32}); + if (peer_class < peer_class_t{0} + || peer_class > peer_class_t{31}) return; TORRENT_ASSERT(st < num_socket_types && st >= 0); if (st < 0 || st >= num_socket_types) return; - m_peer_class_type[st] &= ~(1 << peer_class); + m_peer_class_type[st] &= ~(1 << static_cast(peer_class)); } // ``disallow()`` and ``allow()`` adds and removes a peer class to be @@ -91,25 +93,27 @@ namespace libtorrent // // The ``peer_class`` argument cannot be greater than 31. The bitmasks representing // peer classes in the ``peer_class_type_filter`` are 32 bits. - void disallow(socket_type_t st, int peer_class) + void disallow(socket_type_t st, peer_class_t const peer_class) { - TORRENT_ASSERT(peer_class >= 0); - TORRENT_ASSERT(peer_class < 32); - if (peer_class < 0 || peer_class > 31) return; + TORRENT_ASSERT(peer_class >= peer_class_t{0}); + TORRENT_ASSERT(peer_class < peer_class_t{32}); + if (peer_class < peer_class_t{0} + || peer_class > peer_class_t{31}) return; TORRENT_ASSERT(st < num_socket_types && st >= 0); if (st < 0 || st >= num_socket_types) return; - m_peer_class_type_mask[st] &= ~(1 << peer_class); + m_peer_class_type_mask[st] &= ~(1 << static_cast(peer_class)); } - void allow(socket_type_t st, int peer_class) + void allow(socket_type_t st, peer_class_t const peer_class) { - TORRENT_ASSERT(peer_class >= 0); - TORRENT_ASSERT(peer_class < 32); - if (peer_class < 0 || peer_class > 31) return; + TORRENT_ASSERT(peer_class >= peer_class_t{0}); + TORRENT_ASSERT(peer_class < peer_class_t{32}); + if (peer_class < peer_class_t{0} + || peer_class > peer_class_t{31}) return; TORRENT_ASSERT(st < num_socket_types && st >= 0); if (st < 0 || st >= num_socket_types) return; - m_peer_class_type_mask[st] |= 1 << peer_class; + m_peer_class_type_mask[st] |= 1 << static_cast(peer_class); } // takes a bitmask of peer classes and returns a new bitmask of diff --git a/include/libtorrent/session_handle.hpp b/include/libtorrent/session_handle.hpp index 9689b8e92..e5c5c0643 100644 --- a/include/libtorrent/session_handle.hpp +++ b/include/libtorrent/session_handle.hpp @@ -577,12 +577,19 @@ namespace libtorrent // peer potentially across you changing your IP. void set_key(int key); +#ifdef _MSC_VER +#pragma warning(push, 1) +#pragma warning(disable : 4268) +#endif + // built-in peer classes - enum { - global_peer_class_id, - tcp_peer_class_id, - local_peer_class_id - }; + static constexpr peer_class_t global_peer_class_id{0}; + static constexpr peer_class_t tcp_peer_class_id{1}; + static constexpr peer_class_t local_peer_class_id{2}; + +#ifdef _MSC_VER +#pragma warning(pop) +#endif // ``is_listening()`` will tell you whether or not the session has // successfully opened a listening port. If it hasn't, this function will @@ -609,10 +616,10 @@ namespace libtorrent // belong to their own peer class, apply the following filter:: // // ip_filter f; - // int my_class = ses.create_peer_class("200.1.x.x IP range"); + // peer_class_t my_class = ses.create_peer_class("200.1.x.x IP range"); // f.add_rule(address_v4::from_string("200.1.1.0") // , address_v4::from_string("200.1.255.255") - // , 1 << my_class); + // , 1 << static_cast(my_class)); // ses.set_peer_class_filter(f); // // This setting only applies to new connections, it won't affect existing @@ -655,7 +662,7 @@ namespace libtorrent // make sure to create those early on, to get low identifiers. // // For more information on peer classes, see peer-classes_. - int create_peer_class(char const* name); + peer_class_t create_peer_class(char const* name); // This call dereferences the reference count of the specified peer // class. When creating a peer class it's automatically referenced by 1. diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index 3c40507f6..745f8dd58 100644 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -563,7 +563,7 @@ namespace libtorrent void set_download_limit(int limit); int download_limit() const; - peer_class_t peer_class() const { return peer_class_t(m_peer_class); } + peer_class_t peer_class() const { return m_peer_class; } void set_max_uploads(int limit, bool state_update = true); int max_uploads() const { return int(m_max_uploads); } @@ -1351,7 +1351,7 @@ namespace libtorrent // for torrents who have a bandwidth limit, this is != 0 // and refers to a peer_class in the session. - std::uint16_t m_peer_class = 0; + peer_class_t m_peer_class{0}; // of all peers in m_connections, this is the number // of peers that are outgoing and still waiting to diff --git a/include/libtorrent/units.hpp b/include/libtorrent/units.hpp index 79b0b607a..672ca31ad 100644 --- a/include/libtorrent/units.hpp +++ b/include/libtorrent/units.hpp @@ -94,8 +94,16 @@ namespace aux { UnderlyingType m_val; }; - struct piece_index_tag {}; - struct file_index_tag {}; + // meta function to return the underlying type of a strong_typedef, or the + // type itself if it isn't a strong_typedef + template + struct underlying_index_t { using type = T; }; + + template + struct underlying_index_t> { using type = U; }; + + struct piece_index_tag; + struct file_index_tag; template std::string to_string(strong_typedef const t) diff --git a/src/peer_class.cpp b/src/peer_class.cpp index 2768636a5..44cecda4c 100644 --- a/src/peer_class.cpp +++ b/src/peer_class.cpp @@ -73,20 +73,19 @@ namespace libtorrent priority[peer_connection::download_channel] = (std::max)(1, (std::min)(255, pci->download_priority)); } - peer_class_t peer_class_pool::new_peer_class(std::string const& label) + peer_class_t peer_class_pool::new_peer_class(std::string label) { - peer_class_t ret = 0; + peer_class_t ret{0}; if (!m_free_list.empty()) { ret = m_free_list.back(); m_free_list.pop_back(); - m_peer_classes[ret] = peer_class(label); + m_peer_classes[ret] = peer_class(std::move(label)); } else { - TORRENT_ASSERT(m_peer_classes.size() < 0x100000000); - ret = peer_class_t(m_peer_classes.size()); - m_peer_classes.push_back(peer_class(label)); + ret = m_peer_classes.end_index(); + m_peer_classes.emplace_back(std::move(label)); } return ret; @@ -94,7 +93,7 @@ namespace libtorrent void peer_class_pool::decref(peer_class_t c) { - TORRENT_ASSERT(c < m_peer_classes.size()); + TORRENT_ASSERT(c < m_peer_classes.end_index()); TORRENT_ASSERT(m_peer_classes[c].in_use); TORRENT_ASSERT(m_peer_classes[c].references > 0); @@ -106,7 +105,7 @@ namespace libtorrent void peer_class_pool::incref(peer_class_t c) { - TORRENT_ASSERT(c < m_peer_classes.size()); + TORRENT_ASSERT(c < m_peer_classes.end_index()); TORRENT_ASSERT(m_peer_classes[c].in_use); ++m_peer_classes[c].references; @@ -114,13 +113,13 @@ namespace libtorrent peer_class* peer_class_pool::at(peer_class_t c) { - if (c >= m_peer_classes.size() || !m_peer_classes[c].in_use) return nullptr; + if (c >= m_peer_classes.end_index() || !m_peer_classes[c].in_use) return nullptr; return &m_peer_classes[c]; } peer_class const* peer_class_pool::at(peer_class_t c) const { - if (c >= m_peer_classes.size() || !m_peer_classes[c].in_use) return nullptr; + if (c >= m_peer_classes.end_index() || !m_peer_classes[c].in_use) return nullptr; return &m_peer_classes[c]; } } diff --git a/src/piece_picker.cpp b/src/piece_picker.cpp index 82bf586f3..99201572f 100644 --- a/src/piece_picker.cpp +++ b/src/piece_picker.cpp @@ -42,6 +42,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/bitfield.hpp" #include "libtorrent/random.hpp" #include "libtorrent/alloca.hpp" +#include "libtorrent/aux_/range.hpp" #include "libtorrent/performance_counters.hpp" // for counters #include "libtorrent/alert_types.hpp" // for picker_log_alert diff --git a/src/session_handle.cpp b/src/session_handle.cpp index a6b40261e..f0113a46a 100644 --- a/src/session_handle.cpp +++ b/src/session_handle.cpp @@ -35,6 +35,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/aux_/session_call.hpp" #include "libtorrent/torrent.hpp" #include "libtorrent/lazy_entry.hpp" +#include "libtorrent/peer_class.hpp" #ifndef TORRENT_NO_DEPRECATE #include "libtorrent/read_resume_data.hpp" @@ -45,6 +46,10 @@ using libtorrent::aux::session_impl; namespace libtorrent { + peer_class_t constexpr session_handle::global_peer_class_id; + peer_class_t constexpr session_handle::tcp_peer_class_id; + peer_class_t constexpr session_handle::local_peer_class_id; + template void session_handle::async_call(Fun f, Args&&... a) const { @@ -764,9 +769,9 @@ namespace libtorrent async_call(&session_impl::set_peer_class_type_filter, f); } - int session_handle::create_peer_class(char const* name) + peer_class_t session_handle::create_peer_class(char const* name) { - return sync_call_ret(&session_impl::create_peer_class, name); + return sync_call_ret(&session_impl::create_peer_class, name); } void session_handle::delete_peer_class(int cid) diff --git a/src/session_impl.cpp b/src/session_impl.cpp index b163a3280..900cdd782 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -305,8 +305,8 @@ namespace aux { { // set the default peer_class_filter to use the local peer class // for peers on local networks - std::uint32_t lfilter = 1 << m_local_peer_class; - std::uint32_t gfilter = 1 << m_global_class; + std::uint32_t lfilter = 1 << static_cast(m_local_peer_class); + std::uint32_t gfilter = 1 << static_cast(m_global_class); struct class_mapping { @@ -1116,7 +1116,7 @@ namespace aux { } // anonymous namespace - int session_impl::create_peer_class(char const* name) + peer_class_t session_impl::create_peer_class(char const* name) { TORRENT_ASSERT(is_single_thread()); return m_classes.new_peer_class(name); @@ -1224,7 +1224,7 @@ namespace aux { // filter peer classes based on type peer_class_mask = m_peer_class_type_filter.apply(socket_type, peer_class_mask); - for (peer_class_t i = 0; peer_class_mask; peer_class_mask >>= 1, ++i) + for (peer_class_t i{0}; peer_class_mask; peer_class_mask >>= 1, ++i) { if ((peer_class_mask & 1) == 0) continue; diff --git a/src/torrent.cpp b/src/torrent.cpp index bfcfc484a..91a68e2d7 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -815,7 +815,7 @@ namespace libtorrent // this means that the invariant check that this is called from the // network thread cannot be maintained - TORRENT_ASSERT(m_peer_class == 0); + TORRENT_ASSERT(m_peer_class == peer_class_t{0}); TORRENT_ASSERT(m_connections.empty()); if (!m_connections.empty()) disconnect_all(errors::torrent_aborted, op_bittorrent); @@ -4295,10 +4295,10 @@ namespace libtorrent update_gauge(); stop_announcing(); - if (m_peer_class > 0) + if (m_peer_class > peer_class_t{0}) { m_ses.peer_classes().decref(m_peer_class); - m_peer_class = 0; + m_peer_class = peer_class_t{0}; } error_code ec; @@ -8029,9 +8029,9 @@ namespace libtorrent TORRENT_ASSERT(limit >= -1); if (limit <= 0) limit = 0; - if (m_peer_class == 0 && limit == 0) return; + if (m_peer_class == peer_class_t{0} && limit == 0) return; - if (m_peer_class == 0) + if (m_peer_class == peer_class_t{0}) setup_peer_class(); struct peer_class* tpc = m_ses.peer_classes().at(m_peer_class); @@ -8043,7 +8043,7 @@ namespace libtorrent void torrent::setup_peer_class() { - TORRENT_ASSERT(m_peer_class == 0); + TORRENT_ASSERT(m_peer_class == peer_class_t{0}); m_peer_class = m_ses.peer_classes().new_peer_class(name()); add_class(m_ses.peer_classes(), m_peer_class); } @@ -8052,7 +8052,7 @@ namespace libtorrent { TORRENT_ASSERT(is_single_thread()); - if (m_peer_class == 0) return -1; + if (m_peer_class == peer_class_t{0}) return -1; int limit = m_ses.peer_classes().at(m_peer_class)->channel[channel].throttle(); if (limit == (std::numeric_limits::max)()) limit = -1; return limit; diff --git a/test/setup_transfer.cpp b/test/setup_transfer.cpp index 4a00df1b8..8ba62c125 100644 --- a/test/setup_transfer.cpp +++ b/test/setup_transfer.cpp @@ -793,7 +793,7 @@ setup_transfer(lt::session* ses1, lt::session* ses2, lt::session* ses3 ip_filter f; f.add_rule(address_v4::from_string("0.0.0.0") , address_v4::from_string("255.255.255.255") - , 1 << lt::session::global_peer_class_id); + , 1 << static_cast(lt::session::global_peer_class_id)); ses1->set_peer_class_filter(f); ses2->set_peer_class_filter(f); if (ses3) ses3->set_peer_class_filter(f); diff --git a/test/test_peer_classes.cpp b/test/test_peer_classes.cpp index 984fb51d6..d7cf8d856 100644 --- a/test/test_peer_classes.cpp +++ b/test/test_peer_classes.cpp @@ -63,7 +63,7 @@ TORRENT_TEST(peer_class) peer_class_t id3 = pool.new_peer_class("test3"); - TEST_CHECK(id3 == id2 + 1); + TEST_CHECK(id3 == next(id2)); // make sure refcounting works TEST_EQUAL(class_name(id3, pool), "test3"); @@ -93,19 +93,19 @@ TORRENT_TEST(peer_class) , 0xffffffff) == 0xffffffff); } - filter.disallow((libtorrent::peer_class_type_filter::socket_type_t)0, 0); + filter.disallow((libtorrent::peer_class_type_filter::socket_type_t)0, peer_class_t{0}); TEST_CHECK(filter.apply((libtorrent::peer_class_type_filter::socket_type_t)0 , 0xffffffff) == 0xfffffffe); TEST_CHECK(filter.apply((libtorrent::peer_class_type_filter::socket_type_t)1 , 0xffffffff) == 0xffffffff); - filter.allow((libtorrent::peer_class_type_filter::socket_type_t)0, 0); + filter.allow((libtorrent::peer_class_type_filter::socket_type_t)0, peer_class_t{0}); TEST_CHECK(filter.apply((libtorrent::peer_class_type_filter::socket_type_t)0 , 0xffffffff) == 0xffffffff); TEST_CHECK(filter.apply((libtorrent::peer_class_type_filter::socket_type_t)0, 0) == 0); - filter.add((libtorrent::peer_class_type_filter::socket_type_t)0, 0); + filter.add((libtorrent::peer_class_type_filter::socket_type_t)0, peer_class_t{0}); TEST_CHECK(filter.apply((libtorrent::peer_class_type_filter::socket_type_t)0, 0) == 1); - filter.remove((libtorrent::peer_class_type_filter::socket_type_t)0, 0); + filter.remove((libtorrent::peer_class_type_filter::socket_type_t)0, peer_class_t{0}); TEST_CHECK(filter.apply((libtorrent::peer_class_type_filter::socket_type_t)0, 0) == 0); pool.decref(id2);