use strong_typedef for peer_class_t type (#1595)

use strong_typedef for peer_class_t type
This commit is contained in:
Arvid Norberg 2017-01-21 22:40:19 -05:00 committed by GitHub
parent 173951ec7f
commit 6a701437b6
18 changed files with 296 additions and 110 deletions

View File

@ -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

View File

@ -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 \

View File

@ -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 <deque>
#include <type_traits>
#include "libtorrent/units.hpp"
#include "libtorrent/assert.hpp"
namespace libtorrent { namespace aux {
template <typename T, typename IndexType = int>
struct deque : std::deque<T>
{
using base = std::deque<T>;
using underlying_index = typename underlying_index_t<IndexType>::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<underlying_index>(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<underlying_index>(idx)));
}
IndexType end_index() const
{
TORRENT_ASSERT(this->size() <= std::size_t(std::numeric_limits<underlying_index>::max()));
return IndexType(static_cast<underlying_index>(this->size()));
}
template <typename U = underlying_index, typename Cond
= typename std::enable_if<std::is_signed<U>::value>::type>
void resize(underlying_index s)
{
TORRENT_ASSERT(s >= 0);
this->base::resize(std::size_t(s));
}
template <typename U = underlying_index, typename Cond
= typename std::enable_if<std::is_signed<U>::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<underlying_index>::max)()));
this->base::resize(s);
}
void resize(std::size_t s, T const& v)
{
TORRENT_ASSERT(s <= std::size_t((std::numeric_limits<underlying_index>::max)()));
this->base::resize(s, v);
}
template <typename U = underlying_index, typename Cond
= typename std::enable_if<std::is_signed<U>::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<underlying_index>::max)()));
this->base::reserve(s);
}
};
}}
#endif

View File

@ -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 <typename Iter>
struct iterator_range
{
Iter _begin, _end;
Iter begin() { return _begin; }
Iter end() { return _end; }
};
template <typename T, typename IndexType>
iterator_range<T*> range(vector<T, IndexType>& vec
, IndexType begin, IndexType end)
{
using type = typename underlying_index_t<IndexType>::type;
return {vec.data() + static_cast<type>(begin), vec.data() + static_cast<type>(end)};
}
template <typename T, typename IndexType>
iterator_range<T const*> range(vector<T, IndexType> const& vec
, IndexType begin, IndexType end)
{
using type = typename underlying_index_t<IndexType>::type;
return {vec.data() + static_cast<type>(begin), vec.data() + static_cast<type>(end)};
}
}}
#endif

View File

@ -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;

View File

@ -41,12 +41,6 @@ POSSIBILITY OF SUCH DAMAGE.
namespace libtorrent { namespace aux {
template <typename T>
struct underlying_index_t { using type = T; };
template <typename U, typename Tag>
struct underlying_index_t<aux::strong_typedef<U, Tag>> { using type = U; };
template <typename T, typename IndexType = int>
struct vector : std::vector<T>
{
@ -119,30 +113,6 @@ namespace libtorrent { namespace aux {
}
};
template <typename Iter>
struct iterator_range
{
Iter _begin, _end;
Iter begin() { return _begin; }
Iter end() { return _end; }
};
template <typename T, typename IndexType>
iterator_range<T*> range(vector<T, IndexType>& vec
, IndexType begin, IndexType end)
{
using type = typename underlying_index_t<IndexType>::type;
return {vec.data() + static_cast<type>(begin), vec.data() + static_cast<type>(end)};
}
template <typename T, typename IndexType>
iterator_range<T const*> range(vector<T, IndexType> const& vec
, IndexType begin, IndexType end)
{
using type = typename underlying_index_t<IndexType>::type;
return {vec.data() + static_cast<type>(begin), vec.data() + static_cast<type>(end)};
}
// TODO: find a better place for this function
template <class T, class In, typename Cond = typename std::enable_if<
std::is_integral<T>::value && std::is_integral<In>::value>::type>

View File

@ -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 <vector>
#include <deque>
#include <string>
#include <cstdint>
#include <memory>
namespace libtorrent
{
typedef std::uint32_t peer_class_t;
namespace libtorrent {
namespace aux {
struct peer_class_tag;
}
using peer_class_t = aux::strong_typedef<std::uint32_t, aux::peer_class_tag>;
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<peer_class> m_peer_classes;
aux::deque<peer_class, peer_class_t> m_peer_classes;
// indices in m_peer_classes that are no longer used
std::vector<peer_class_t> m_free_list;

View File

@ -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<std::uint32_t>(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<std::uint32_t>(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<std::uint32_t>(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<std::uint32_t>(peer_class);
}
// takes a bitmask of peer classes and returns a new bitmask of

View File

@ -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<std::uint32_t>(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.

View File

@ -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

View File

@ -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 <typename T>
struct underlying_index_t { using type = T; };
template <typename U, typename Tag>
struct underlying_index_t<aux::strong_typedef<U, Tag>> { using type = U; };
struct piece_index_tag;
struct file_index_tag;
template <typename T, typename Tag>
std::string to_string(strong_typedef<T, Tag> const t)

View File

@ -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];
}
}

View File

@ -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

View File

@ -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 <typename Fun, typename... Args>
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<int>(&session_impl::create_peer_class, name);
return sync_call_ret<peer_class_t>(&session_impl::create_peer_class, name);
}
void session_handle::delete_peer_class(int cid)

View File

@ -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<std::uint32_t>(m_local_peer_class);
std::uint32_t gfilter = 1 << static_cast<std::uint32_t>(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;

View File

@ -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<int>::max)()) limit = -1;
return limit;

View File

@ -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<std::uint32_t>(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);

View File

@ -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);