complete the error handling test and make it part of the default simulation test suite. It will run a file transfer between two clients repeatedly, each time cause another memory allocation fail, until every single memory allocation has failed once. Any invariant check failure, assertion or signal will cause the test to fail
This commit is contained in:
parent
97ceeab9e3
commit
3a9861e237
4
Jamfile
4
Jamfile
|
@ -519,12 +519,12 @@ variant test_release : release
|
|||
variant test_debug : debug
|
||||
: <logging>on
|
||||
<invariant-checks>full <boost-link>shared
|
||||
<export-extra>on <debug-iterators>on <threading>multi <asserts>on
|
||||
<export-extra>on <threading>multi <asserts>on
|
||||
;
|
||||
variant test_barebones : debug
|
||||
: <ipv6>off <dht>off <extensions>off <logging>off <boost-link>shared
|
||||
<deprecated-functions>off <invariant-checks>off
|
||||
<export-extra>on <debug-iterators>on <threading>multi <asserts>on
|
||||
<export-extra>on <threading>multi <asserts>on
|
||||
;
|
||||
variant test_arm : debug
|
||||
: <ipv6>off <dht>off <extensions>off <logging>off
|
||||
|
|
|
@ -88,7 +88,7 @@ build_script:
|
|||
# simulations
|
||||
- cd %ROOT_DIRECTORY%\simulation
|
||||
- if defined sim (
|
||||
b2.exe --hash openssl-version=pre1.1 warnings-as-errors=on -j2 %compiler% address-model=%model% picker-debugging=on invariant-checks=full variant=%variant% deprecated-functions=off %linkflags% %include% link=shared crypto=built-in testing.execute=off
|
||||
b2.exe --hash openssl-version=pre1.1 warnings-as-errors=on -j2 %compiler% address-model=%model% debug-iterators=off picker-debugging=on invariant-checks=full test_debug %linkflags% %include% boost-link=default link=static crypto=built-in define=BOOST_ASIO_DISABLE_IOCP testing.execute=off
|
||||
)
|
||||
|
||||
test_script:
|
||||
|
@ -107,7 +107,9 @@ test_script:
|
|||
# specifiers when debug iterators are enabled. Specifically, constructors that
|
||||
# allocate memory are still marked as noexcept. That results in program
|
||||
# termination
|
||||
# the IOCP backend in asio appears to have an issue where it hangs under
|
||||
# certain unexpected terminations (through exceptions)
|
||||
- cd %ROOT_DIRECTORY%\simulation
|
||||
- if defined sim (
|
||||
b2.exe --hash openssl-version=pre1.1 warnings-as-errors=on -j2 %compiler% address-model=%model% debug-iterators=off picker-debugging=on invariant-checks=full test_debug %linkflags% %include% boost-link=default link=static crypto=built-in
|
||||
b2.exe --hash openssl-version=pre1.1 warnings-as-errors=on -j2 %compiler% address-model=%model% debug-iterators=off picker-debugging=on invariant-checks=full test_debug %linkflags% %include% boost-link=default link=static crypto=built-in define=BOOST_ASIO_DISABLE_IOCP
|
||||
)
|
||||
|
|
|
@ -1261,7 +1261,7 @@ namespace aux {
|
|||
|
||||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
bool should_log() const override;
|
||||
void session_log(char const* fmt, ...) const override TORRENT_FORMAT(2,3);
|
||||
void session_log(char const* fmt, ...) const noexcept override TORRENT_FORMAT(2,3);
|
||||
#endif
|
||||
|
||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||
|
@ -1314,7 +1314,7 @@ namespace aux {
|
|||
, error_code const& ec, const std::string& str
|
||||
, seconds32 retry_interval) override;
|
||||
bool should_log() const override;
|
||||
void debug_log(const char* fmt, ...) const override TORRENT_FORMAT(2,3);
|
||||
void debug_log(const char* fmt, ...) const noexcept override TORRENT_FORMAT(2,3);
|
||||
session_interface& m_ses;
|
||||
private:
|
||||
// explicitly disallow assignment, to silence msvc warning
|
||||
|
|
|
@ -286,7 +286,9 @@ namespace aux {
|
|||
, buffer_allocator_interface
|
||||
{
|
||||
disk_io_thread(io_service& ios, counters& cnt);
|
||||
#if TORRENT_USE_ASSERTS
|
||||
~disk_io_thread();
|
||||
#endif
|
||||
|
||||
void set_settings(settings_pack const* sett);
|
||||
|
||||
|
|
|
@ -160,6 +160,16 @@ namespace libtorrent {
|
|||
// can handle common cases of packet size by 3 pools
|
||||
struct TORRENT_EXTRA_EXPORT packet_pool : private single_threaded
|
||||
{
|
||||
// there's a bug in GCC where allocating these in
|
||||
// member initializer expressions won't propagate exceptions.
|
||||
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80683
|
||||
packet_pool()
|
||||
: m_syn_slab(TORRENT_UTP_HEADER)
|
||||
, m_mtu_floor_slab(mtu_floor_size)
|
||||
, m_mtu_ceiling_slab(mtu_ceiling_size)
|
||||
{}
|
||||
packet_pool(packet_pool&&) = default;
|
||||
|
||||
packet_ptr acquire(int const allocate)
|
||||
{
|
||||
TORRENT_ASSERT(is_single_thread());
|
||||
|
@ -202,9 +212,9 @@ namespace libtorrent {
|
|||
}
|
||||
static int const mtu_floor_size = TORRENT_INET_MIN_MTU - TORRENT_IPV4_HEADER - TORRENT_UDP_HEADER;
|
||||
static int const mtu_ceiling_size = TORRENT_ETHERNET_MTU - TORRENT_IPV4_HEADER - TORRENT_UDP_HEADER;
|
||||
packet_slab m_syn_slab{ TORRENT_UTP_HEADER };
|
||||
packet_slab m_mtu_floor_slab{ mtu_floor_size };
|
||||
packet_slab m_mtu_ceiling_slab{ mtu_ceiling_size };
|
||||
packet_slab m_syn_slab;
|
||||
packet_slab m_mtu_floor_slab;
|
||||
packet_slab m_mtu_ceiling_slab;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -526,9 +526,9 @@ namespace aux {
|
|||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
bool should_log(peer_log_alert::direction_t direction) const override;
|
||||
void peer_log(peer_log_alert::direction_t direction
|
||||
, char const* event, char const* fmt, ...) const override TORRENT_FORMAT(4,5);
|
||||
, char const* event, char const* fmt, ...) const noexcept override TORRENT_FORMAT(4,5);
|
||||
void peer_log(peer_log_alert::direction_t direction
|
||||
, char const* event) const;
|
||||
, char const* event) const noexcept;
|
||||
|
||||
time_point m_connect_time;
|
||||
time_point m_bitfield_time;
|
||||
|
|
|
@ -65,7 +65,7 @@ namespace libtorrent {
|
|||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
virtual bool should_log(peer_log_alert::direction_t direction) const = 0;
|
||||
virtual void peer_log(peer_log_alert::direction_t direction
|
||||
, char const* event, char const* fmt = "", ...) const TORRENT_FORMAT(4,5) = 0;
|
||||
, char const* event, char const* fmt = "", ...) const noexcept TORRENT_FORMAT(4,5) = 0;
|
||||
#endif
|
||||
protected:
|
||||
~peer_connection_interface() {}
|
||||
|
|
|
@ -1023,7 +1023,7 @@ namespace libtorrent {
|
|||
// LOGGING
|
||||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
bool should_log() const override;
|
||||
void debug_log(const char* fmt, ...) const override TORRENT_FORMAT(2,3);
|
||||
void debug_log(const char* fmt, ...) const noexcept override TORRENT_FORMAT(2,3);
|
||||
|
||||
void log_to_all_peers(char const* message);
|
||||
time_point m_dht_start_time;
|
||||
|
|
|
@ -249,7 +249,7 @@ namespace libtorrent {
|
|||
|
||||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
virtual bool should_log() const = 0;
|
||||
virtual void debug_log(const char* fmt, ...) const TORRENT_FORMAT(2,3) = 0;
|
||||
virtual void debug_log(const char* fmt, ...) const noexcept TORRENT_FORMAT(2,3) = 0;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -51,8 +51,6 @@ alias libtorrent-sims :
|
|||
[ run test_fast_extensions.cpp ]
|
||||
[ run test_file_pool.cpp ]
|
||||
[ run test_save_resume.cpp ]
|
||||
[ run test_error_handling.cpp ]
|
||||
;
|
||||
|
||||
run test_error_handling.cpp ;
|
||||
explicit test_error_handling ;
|
||||
|
||||
|
|
|
@ -51,6 +51,10 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
using namespace sim;
|
||||
|
||||
#if defined _MSC_VER && _ITERATOR_DEBUG_LEVEL > 0
|
||||
// https://developercommunity.visualstudio.com/content/problem/140200/c-stl-stdvector-constructor-declared-with-noexcept.html
|
||||
#error "msvc's standard library does not support bad_alloc with debug iterators. This test only works with debug iterators disabled on msvc. _ITERATOR_DEBUG_LEVEL=0"
|
||||
#endif
|
||||
|
||||
std::string make_ep_string(char const* address, bool const is_v6
|
||||
, char const* port)
|
||||
|
@ -105,7 +109,7 @@ void run_test(HandleAlerts const& on_alert, Test const& test)
|
|||
|
||||
// only monitor alerts for session 0 (the downloader)
|
||||
print_alerts(*ses[0], [=](lt::session& ses, lt::alert const* a) {
|
||||
if (auto ta = alert_cast<lt::torrent_added_alert>(a))
|
||||
if (auto ta = alert_cast<lt::add_torrent_alert>(a))
|
||||
{
|
||||
ta->handle.connect_peer(lt::tcp::endpoint(peer1, 6881));
|
||||
}
|
||||
|
@ -149,6 +153,22 @@ void* operator new(std::size_t sz)
|
|||
{
|
||||
char stack[10000];
|
||||
print_backtrace(stack, sizeof(stack), 40, nullptr);
|
||||
#ifdef _MSC_VER
|
||||
// this is a bit unfortunate. Some MSVC standard containers really don't move
|
||||
// with noexcept, by actually allocating memory (i.e. it's not just a matter
|
||||
// of accidentally missing noexcept specifiers). The heterogeneous queue used
|
||||
// by the alert manager requires alerts to be noexcept move constructable and
|
||||
// move assignable, which they claim to be, even though on MSVC some of them
|
||||
// aren't. Things will improve in C++17 and it doesn't seem worth the trouble
|
||||
// to make the heterogeneous queue support throwing moves, nor to replace all
|
||||
// standard types with variants that can move noexcept.
|
||||
if (std::strstr(stack, " libtorrent::entry::operator= ") != nullptr
|
||||
|| std::strstr(stack, " libtorrent::aux::noexcept_movable<std::map<") != nullptr)
|
||||
{
|
||||
++g_alloc_counter;
|
||||
return std::malloc(sz);
|
||||
}
|
||||
#endif
|
||||
std::printf("\n\nthrowing bad_alloc (as part of test)\n%s\n\n\n", stack);
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
@ -162,7 +182,7 @@ void operator delete(void* ptr) noexcept
|
|||
|
||||
TORRENT_TEST(error_handling)
|
||||
{
|
||||
for (int i = 0; i < 3000; ++i)
|
||||
for (int i = 0; i < 8000; ++i)
|
||||
{
|
||||
// this will clear the history of all output we've printed so far.
|
||||
// if we encounter an error from now on, we'll only print the relevant
|
||||
|
@ -176,7 +196,7 @@ TORRENT_TEST(error_handling)
|
|||
std::printf("\n\n === ROUND %d ===\n\n", i);
|
||||
try
|
||||
{
|
||||
g_alloc_counter = 100 + i;
|
||||
g_alloc_counter = i;
|
||||
using namespace lt;
|
||||
run_test(
|
||||
[](lt::session&, lt::alert const*) {},
|
||||
|
@ -211,5 +231,12 @@ TORRENT_TEST(error_handling)
|
|||
// continue, we won't exercise any new code paths
|
||||
if (g_alloc_counter > 0) break;
|
||||
}
|
||||
|
||||
// if this fails, we need to raise the limit in the loop above
|
||||
TEST_CHECK(g_alloc_counter > 0);
|
||||
|
||||
// we don't want any part of the actual test framework to suffer from failed
|
||||
// allocations, so bump the counter
|
||||
g_alloc_counter = 1000000;
|
||||
}
|
||||
|
||||
|
|
|
@ -329,7 +329,6 @@ cached_piece_entry::~cached_piece_entry()
|
|||
{
|
||||
for (int i = 0; i < blocks_in_piece; ++i)
|
||||
{
|
||||
TORRENT_ASSERT(blocks[i].buf == nullptr);
|
||||
TORRENT_ASSERT(!blocks[i].pending);
|
||||
TORRENT_ASSERT(blocks[i].refcount == 0);
|
||||
TORRENT_ASSERT(blocks[i].hashing_count == 0);
|
||||
|
|
|
@ -227,6 +227,9 @@ constexpr disk_job_flags_t disk_interface::cache_hit;
|
|||
TORRENT_ASSERT(storage);
|
||||
if (m_free_slots.empty())
|
||||
{
|
||||
// make sure there's always space in here to add another free slot.
|
||||
// stopping a torrent should never fail because it needs to allocate memory
|
||||
m_free_slots.reserve(m_torrents.size() + 1);
|
||||
storage_index_t const idx = m_torrents.end_index();
|
||||
m_torrents.emplace_back(std::move(storage));
|
||||
m_torrents.back()->set_storage_index(idx);
|
||||
|
@ -251,21 +254,15 @@ constexpr disk_job_flags_t disk_interface::cache_hit;
|
|||
}
|
||||
}
|
||||
|
||||
#if TORRENT_USE_ASSERTS
|
||||
disk_io_thread::~disk_io_thread()
|
||||
{
|
||||
DLOG("destructing disk_io_thread\n");
|
||||
|
||||
#if TORRENT_USE_ASSERTS
|
||||
// by now, all pieces should have been evicted
|
||||
auto pieces = m_disk_cache.all_pieces();
|
||||
TORRENT_ASSERT(pieces.first == pieces.second);
|
||||
#endif
|
||||
|
||||
TORRENT_ASSERT(m_magic == 0x1337);
|
||||
#if TORRENT_USE_ASSERTS
|
||||
m_magic = 0xdead;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
void disk_io_thread::abort(bool const wait)
|
||||
{
|
||||
|
|
|
@ -182,6 +182,11 @@ namespace libtorrent {
|
|||
, print_endpoint(local_ep).c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
// this counter should not be incremeneted until we know constructing this
|
||||
// peer object can't fail anymore
|
||||
if (m_connecting && t) t->inc_num_connecting(m_peer_info);
|
||||
|
||||
#if TORRENT_USE_ASSERTS
|
||||
piece_failed = false;
|
||||
m_in_constructor = false;
|
||||
|
@ -372,8 +377,6 @@ namespace libtorrent {
|
|||
// if this is an incoming connection, we're done here
|
||||
if (!m_connecting) return;
|
||||
|
||||
if (m_connecting && t) t->inc_num_connecting(m_peer_info);
|
||||
|
||||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
if (should_log(peer_log_alert::outgoing))
|
||||
{
|
||||
|
@ -529,14 +532,14 @@ namespace libtorrent {
|
|||
}
|
||||
|
||||
void peer_connection::peer_log(peer_log_alert::direction_t direction
|
||||
, char const* event) const
|
||||
, char const* event) const noexcept
|
||||
{
|
||||
peer_log(direction, event, "");
|
||||
}
|
||||
|
||||
TORRENT_FORMAT(4,5)
|
||||
void peer_connection::peer_log(peer_log_alert::direction_t direction
|
||||
, char const* event, char const* fmt, ...) const
|
||||
, char const* event, char const* fmt, ...) const noexcept try
|
||||
{
|
||||
TORRENT_ASSERT(is_single_thread());
|
||||
|
||||
|
@ -555,6 +558,7 @@ namespace libtorrent {
|
|||
va_end(v);
|
||||
|
||||
}
|
||||
catch (std::exception const&) {}
|
||||
#endif
|
||||
|
||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||
|
@ -797,8 +801,6 @@ namespace libtorrent {
|
|||
|
||||
// INVARIANT_CHECK;
|
||||
TORRENT_ASSERT(!m_in_constructor);
|
||||
TORRENT_ASSERT(m_disconnecting);
|
||||
TORRENT_ASSERT(m_disconnect_started);
|
||||
TORRENT_ASSERT(!m_destructed);
|
||||
#if TORRENT_USE_ASSERTS
|
||||
m_destructed = true;
|
||||
|
@ -836,7 +838,6 @@ namespace libtorrent {
|
|||
TORRENT_ASSERT(t || !m_connecting);
|
||||
|
||||
// we should really have dealt with this already
|
||||
TORRENT_ASSERT(!m_connecting);
|
||||
if (m_connecting)
|
||||
{
|
||||
m_counters.inc_stats_counter(counters::num_peers_half_open, -1);
|
||||
|
@ -853,11 +854,6 @@ namespace libtorrent {
|
|||
#endif
|
||||
TORRENT_ASSERT(m_request_queue.empty());
|
||||
TORRENT_ASSERT(m_download_queue.empty());
|
||||
|
||||
#if TORRENT_USE_ASSERTS
|
||||
if (m_peer_info)
|
||||
TORRENT_ASSERT(m_peer_info->connection == nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool peer_connection::on_parole() const
|
||||
|
@ -4385,7 +4381,7 @@ namespace libtorrent {
|
|||
m_queued_time_critical = 0;
|
||||
|
||||
#if TORRENT_USE_INVARIANT_CHECKS
|
||||
check_invariant();
|
||||
try { check_invariant(); } catch (std::exception const&) {}
|
||||
#endif
|
||||
t->remove_peer(self());
|
||||
|
||||
|
@ -6326,10 +6322,6 @@ namespace libtorrent {
|
|||
TORRENT_ASSERT(m_request_queue.empty());
|
||||
TORRENT_ASSERT(m_disconnect_started);
|
||||
}
|
||||
else if (!m_in_constructor)
|
||||
{
|
||||
TORRENT_ASSERT(m_ses.has_peer(this));
|
||||
}
|
||||
|
||||
TORRENT_ASSERT(m_outstanding_bytes >= 0);
|
||||
if (t && t->valid_metadata() && !m_disconnecting)
|
||||
|
|
|
@ -882,12 +882,13 @@ namespace aux {
|
|||
session_log(" aborting all connections (%d)", int(m_connections.size()));
|
||||
#endif
|
||||
// abort all connections
|
||||
// keep in mind that connections that are not associated with a torrent
|
||||
// will remove its entry from m_connections immediately, which means we
|
||||
// can't iterate over it here
|
||||
auto conns = m_connections;
|
||||
for (auto const& p : conns)
|
||||
for (connection_map::iterator i = m_connections.begin();
|
||||
i != m_connections.end();)
|
||||
{
|
||||
peer_connection* p = (*i).get();
|
||||
++i;
|
||||
p->disconnect(errors::stopping_torrent, operation_t::bittorrent);
|
||||
}
|
||||
|
||||
// close the listen sockets
|
||||
for (auto const& l : m_listen_sockets)
|
||||
|
@ -4533,7 +4534,7 @@ namespace {
|
|||
}
|
||||
|
||||
TORRENT_FORMAT(2,3)
|
||||
void session_impl::session_log(char const* fmt, ...) const
|
||||
void session_impl::session_log(char const* fmt, ...) const noexcept try
|
||||
{
|
||||
if (!m_alerts.should_post<log_alert>()) return;
|
||||
|
||||
|
@ -4542,6 +4543,7 @@ namespace {
|
|||
m_alerts.emplace_alert<log_alert>(fmt, v);
|
||||
va_end(v);
|
||||
}
|
||||
catch (std::exception const&) {}
|
||||
#endif
|
||||
|
||||
void session_impl::get_torrent_status(std::vector<torrent_status>* ret
|
||||
|
@ -7147,7 +7149,7 @@ namespace {
|
|||
return m_ses.alerts().should_post<log_alert>();
|
||||
}
|
||||
|
||||
void tracker_logger::debug_log(const char* fmt, ...) const
|
||||
void tracker_logger::debug_log(const char* fmt, ...) const noexcept try
|
||||
{
|
||||
if (!m_ses.alerts().should_post<log_alert>()) return;
|
||||
|
||||
|
@ -7156,5 +7158,6 @@ namespace {
|
|||
m_ses.alerts().emplace_alert<log_alert>(fmt, v);
|
||||
va_end(v);
|
||||
}
|
||||
catch (std::exception const&) {}
|
||||
#endif // TORRENT_DISABLE_LOGGING
|
||||
}}
|
||||
|
|
|
@ -4361,8 +4361,23 @@ namespace libtorrent {
|
|||
// the torrent object from there
|
||||
if (m_storage)
|
||||
{
|
||||
m_ses.disk_thread().async_stop_torrent(m_storage
|
||||
, std::bind(&torrent::on_torrent_aborted, shared_from_this()));
|
||||
try {
|
||||
m_ses.disk_thread().async_stop_torrent(m_storage
|
||||
, std::bind(&torrent::on_torrent_aborted, shared_from_this()));
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
TORRENT_UNUSED(e);
|
||||
m_storage.reset();
|
||||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
debug_log("Failed to flush disk cache: %s", e.what());
|
||||
#endif
|
||||
// clients may rely on this alert to be posted, so it's probably a
|
||||
// good idea to post it here, even though we failed
|
||||
// TODO: 3 should this alert have an error code in it?
|
||||
if (alerts().should_post<cache_flushed_alert>())
|
||||
alerts().emplace_alert<cache_flushed_alert>(get_handle());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4401,6 +4416,10 @@ namespace libtorrent {
|
|||
// have been destructed
|
||||
if (m_peer_list) m_peer_list->clear();
|
||||
m_connections.clear();
|
||||
m_peers_to_disconnect.clear();
|
||||
m_num_uploads = 0;
|
||||
m_num_connecting = 0;
|
||||
m_num_connecting_seeds = 0;
|
||||
}
|
||||
|
||||
void torrent::set_super_seeding(bool on)
|
||||
|
@ -6877,22 +6896,7 @@ namespace libtorrent {
|
|||
peers_erased(st.erased);
|
||||
|
||||
m_peers_to_disconnect.reserve(m_connections.size() + 1);
|
||||
|
||||
TORRENT_ASSERT(sorted_find(m_connections, p) == m_connections.end());
|
||||
TORRENT_ASSERT(m_iterating_connections == 0);
|
||||
sorted_insert(m_connections, p);
|
||||
update_want_peers();
|
||||
update_want_tick();
|
||||
|
||||
if (p->peer_info_struct() && p->peer_info_struct()->seed)
|
||||
{
|
||||
TORRENT_ASSERT(m_num_seeds < 0xffff);
|
||||
++m_num_seeds;
|
||||
}
|
||||
|
||||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
debug_log("incoming peer (%d)", num_peers());
|
||||
#endif
|
||||
m_connections.reserve(m_connections.size() + 1);
|
||||
|
||||
#if TORRENT_USE_ASSERTS
|
||||
error_code ec;
|
||||
|
@ -6956,13 +6960,33 @@ namespace libtorrent {
|
|||
if (m_share_mode)
|
||||
recalc_share_mode();
|
||||
|
||||
// once we add the peer to our m_connections list, we can't throw an
|
||||
// exception. That will end up violating an invariant between the session,
|
||||
// torrent and peers
|
||||
TORRENT_ASSERT(sorted_find(m_connections, p) == m_connections.end());
|
||||
TORRENT_ASSERT(m_iterating_connections == 0);
|
||||
sorted_insert(m_connections, p);
|
||||
update_want_peers();
|
||||
update_want_tick();
|
||||
|
||||
if (p->peer_info_struct() && p->peer_info_struct()->seed)
|
||||
{
|
||||
TORRENT_ASSERT(m_num_seeds < 0xffff);
|
||||
++m_num_seeds;
|
||||
}
|
||||
|
||||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
if (should_log())
|
||||
debug_log("incoming peer (%d)", num_peers());
|
||||
#endif
|
||||
|
||||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
if (should_log()) try
|
||||
{
|
||||
debug_log("ATTACHED CONNECTION \"%s\" connections: %d limit: %d"
|
||||
, print_endpoint(p->remote()).c_str(), num_peers()
|
||||
, m_max_connections);
|
||||
}
|
||||
catch (std::exception const&) {}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
|
@ -7775,7 +7799,7 @@ namespace libtorrent {
|
|||
|
||||
TORRENT_ASSERT(is_single_thread());
|
||||
// this fires during disconnecting peers
|
||||
// if (is_paused()) TORRENT_ASSERT(num_peers() == 0 || m_graceful_pause_mode);
|
||||
if (is_paused()) TORRENT_ASSERT(num_peers() == 0 || m_graceful_pause_mode);
|
||||
|
||||
int seeds = 0;
|
||||
int num_uploads = 0;
|
||||
|
@ -7784,10 +7808,6 @@ namespace libtorrent {
|
|||
std::map<piece_block, int> num_requests;
|
||||
for (peer_connection const* peer : *this)
|
||||
{
|
||||
#ifdef TORRENT_EXPENSIVE_INVARIANT_CHECKS
|
||||
// make sure this peer is not a dangling pointer
|
||||
TORRENT_ASSERT(m_ses.has_peer(peer));
|
||||
#endif
|
||||
peer_connection const& p = *peer;
|
||||
|
||||
if (p.is_connecting()) ++num_connecting;
|
||||
|
@ -7813,16 +7833,19 @@ namespace libtorrent {
|
|||
if (associated_torrent != this && associated_torrent != nullptr)
|
||||
TORRENT_ASSERT_FAIL();
|
||||
}
|
||||
TORRENT_ASSERT(num_uploads == int(m_num_uploads));
|
||||
TORRENT_ASSERT(seeds == int(m_num_seeds));
|
||||
TORRENT_ASSERT(num_connecting == int(m_num_connecting));
|
||||
TORRENT_ASSERT(num_connecting_seeds == int(m_num_connecting_seeds));
|
||||
TORRENT_ASSERT(int(m_num_uploads) <= num_peers());
|
||||
TORRENT_ASSERT(int(m_num_seeds) <= num_peers());
|
||||
TORRENT_ASSERT(int(m_num_connecting) <= num_peers());
|
||||
TORRENT_ASSERT(int(m_num_connecting_seeds) <= num_peers());
|
||||
TORRENT_ASSERT(int(m_num_connecting) + int(m_num_seeds) >= int(m_num_connecting_seeds));
|
||||
TORRENT_ASSERT(int(m_num_connecting) + int(m_num_seeds) - int(m_num_connecting_seeds) <= num_peers());
|
||||
TORRENT_ASSERT_VAL(num_uploads == int(m_num_uploads), int(m_num_uploads) - num_uploads);
|
||||
TORRENT_ASSERT_VAL(seeds == int(m_num_seeds), int(m_num_seeds) - seeds);
|
||||
TORRENT_ASSERT_VAL(num_connecting == int(m_num_connecting), int(m_num_connecting) - num_connecting);
|
||||
TORRENT_ASSERT_VAL(num_connecting_seeds == int(m_num_connecting_seeds)
|
||||
, int(m_num_connecting_seeds) - num_connecting_seeds);
|
||||
TORRENT_ASSERT_VAL(int(m_num_uploads) <= num_peers(), m_num_uploads - num_peers());
|
||||
TORRENT_ASSERT_VAL(int(m_num_seeds) <= num_peers(), m_num_seeds - num_peers());
|
||||
TORRENT_ASSERT_VAL(int(m_num_connecting) <= num_peers(), int(m_num_connecting) - num_peers());
|
||||
TORRENT_ASSERT_VAL(int(m_num_connecting_seeds) <= num_peers(), int(m_num_connecting_seeds) - num_peers());
|
||||
TORRENT_ASSERT_VAL(int(m_num_connecting) + int(m_num_seeds) >= int(m_num_connecting_seeds)
|
||||
, int(m_num_connecting_seeds) - (int(m_num_connecting) + int(m_num_seeds)));
|
||||
TORRENT_ASSERT_VAL(int(m_num_connecting) + int(m_num_seeds) - int(m_num_connecting_seeds) <= num_peers()
|
||||
, num_peers() - (int(m_num_connecting) + int(m_num_seeds) - int(m_num_connecting_seeds)));
|
||||
|
||||
if (has_picker())
|
||||
{
|
||||
|
@ -10979,7 +11002,7 @@ namespace {
|
|||
}
|
||||
|
||||
TORRENT_FORMAT(2,3)
|
||||
void torrent::debug_log(char const* fmt, ...) const
|
||||
void torrent::debug_log(char const* fmt, ...) const noexcept try
|
||||
{
|
||||
if (!alerts().should_post<torrent_log_alert>()) return;
|
||||
|
||||
|
@ -10989,6 +11012,7 @@ namespace {
|
|||
const_cast<torrent*>(this)->get_handle(), fmt, v);
|
||||
va_end(v);
|
||||
}
|
||||
catch (std::exception const&) {}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
|
|
@ -70,11 +70,11 @@ struct mock_peer_connection
|
|||
virtual ~mock_peer_connection() = default;
|
||||
|
||||
#if !defined TORRENT_DISABLE_LOGGING
|
||||
bool should_log(peer_log_alert::direction_t) const override
|
||||
bool should_log(peer_log_alert::direction_t) const noexcept override
|
||||
{ return true; }
|
||||
|
||||
void peer_log(peer_log_alert::direction_t dir, char const* event
|
||||
, char const* fmt, ...) const override
|
||||
, char const* fmt, ...) const noexcept override
|
||||
{
|
||||
va_list v;
|
||||
va_start(v, fmt);
|
||||
|
|
Loading…
Reference in New Issue