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
|
variant test_debug : debug
|
||||||
: <logging>on
|
: <logging>on
|
||||||
<invariant-checks>full <boost-link>shared
|
<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
|
variant test_barebones : debug
|
||||||
: <ipv6>off <dht>off <extensions>off <logging>off <boost-link>shared
|
: <ipv6>off <dht>off <extensions>off <logging>off <boost-link>shared
|
||||||
<deprecated-functions>off <invariant-checks>off
|
<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
|
variant test_arm : debug
|
||||||
: <ipv6>off <dht>off <extensions>off <logging>off
|
: <ipv6>off <dht>off <extensions>off <logging>off
|
||||||
|
|
|
@ -88,7 +88,7 @@ build_script:
|
||||||
# simulations
|
# simulations
|
||||||
- cd %ROOT_DIRECTORY%\simulation
|
- cd %ROOT_DIRECTORY%\simulation
|
||||||
- if defined sim (
|
- 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:
|
test_script:
|
||||||
|
@ -107,7 +107,9 @@ test_script:
|
||||||
# specifiers when debug iterators are enabled. Specifically, constructors that
|
# specifiers when debug iterators are enabled. Specifically, constructors that
|
||||||
# allocate memory are still marked as noexcept. That results in program
|
# allocate memory are still marked as noexcept. That results in program
|
||||||
# termination
|
# termination
|
||||||
|
# the IOCP backend in asio appears to have an issue where it hangs under
|
||||||
|
# certain unexpected terminations (through exceptions)
|
||||||
- cd %ROOT_DIRECTORY%\simulation
|
- cd %ROOT_DIRECTORY%\simulation
|
||||||
- if defined sim (
|
- 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
|
#ifndef TORRENT_DISABLE_LOGGING
|
||||||
bool should_log() const override;
|
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
|
#endif
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||||
|
@ -1314,7 +1314,7 @@ namespace aux {
|
||||||
, error_code const& ec, const std::string& str
|
, error_code const& ec, const std::string& str
|
||||||
, seconds32 retry_interval) override;
|
, seconds32 retry_interval) override;
|
||||||
bool should_log() const 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;
|
session_interface& m_ses;
|
||||||
private:
|
private:
|
||||||
// explicitly disallow assignment, to silence msvc warning
|
// explicitly disallow assignment, to silence msvc warning
|
||||||
|
|
|
@ -286,7 +286,9 @@ namespace aux {
|
||||||
, buffer_allocator_interface
|
, buffer_allocator_interface
|
||||||
{
|
{
|
||||||
disk_io_thread(io_service& ios, counters& cnt);
|
disk_io_thread(io_service& ios, counters& cnt);
|
||||||
|
#if TORRENT_USE_ASSERTS
|
||||||
~disk_io_thread();
|
~disk_io_thread();
|
||||||
|
#endif
|
||||||
|
|
||||||
void set_settings(settings_pack const* sett);
|
void set_settings(settings_pack const* sett);
|
||||||
|
|
||||||
|
|
|
@ -160,6 +160,16 @@ namespace libtorrent {
|
||||||
// can handle common cases of packet size by 3 pools
|
// can handle common cases of packet size by 3 pools
|
||||||
struct TORRENT_EXTRA_EXPORT packet_pool : private single_threaded
|
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)
|
packet_ptr acquire(int const allocate)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(is_single_thread());
|
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_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;
|
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_syn_slab;
|
||||||
packet_slab m_mtu_floor_slab{ mtu_floor_size };
|
packet_slab m_mtu_floor_slab;
|
||||||
packet_slab m_mtu_ceiling_slab{ mtu_ceiling_size };
|
packet_slab m_mtu_ceiling_slab;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -526,9 +526,9 @@ namespace aux {
|
||||||
#ifndef TORRENT_DISABLE_LOGGING
|
#ifndef TORRENT_DISABLE_LOGGING
|
||||||
bool should_log(peer_log_alert::direction_t direction) const override;
|
bool should_log(peer_log_alert::direction_t direction) const override;
|
||||||
void peer_log(peer_log_alert::direction_t direction
|
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
|
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_connect_time;
|
||||||
time_point m_bitfield_time;
|
time_point m_bitfield_time;
|
||||||
|
|
|
@ -65,7 +65,7 @@ namespace libtorrent {
|
||||||
#ifndef TORRENT_DISABLE_LOGGING
|
#ifndef TORRENT_DISABLE_LOGGING
|
||||||
virtual bool should_log(peer_log_alert::direction_t direction) const = 0;
|
virtual bool should_log(peer_log_alert::direction_t direction) const = 0;
|
||||||
virtual void peer_log(peer_log_alert::direction_t direction
|
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
|
#endif
|
||||||
protected:
|
protected:
|
||||||
~peer_connection_interface() {}
|
~peer_connection_interface() {}
|
||||||
|
|
|
@ -1023,7 +1023,7 @@ namespace libtorrent {
|
||||||
// LOGGING
|
// LOGGING
|
||||||
#ifndef TORRENT_DISABLE_LOGGING
|
#ifndef TORRENT_DISABLE_LOGGING
|
||||||
bool should_log() const 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);
|
||||||
|
|
||||||
void log_to_all_peers(char const* message);
|
void log_to_all_peers(char const* message);
|
||||||
time_point m_dht_start_time;
|
time_point m_dht_start_time;
|
||||||
|
|
|
@ -249,7 +249,7 @@ namespace libtorrent {
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_LOGGING
|
#ifndef TORRENT_DISABLE_LOGGING
|
||||||
virtual bool should_log() const = 0;
|
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
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -51,8 +51,6 @@ alias libtorrent-sims :
|
||||||
[ run test_fast_extensions.cpp ]
|
[ run test_fast_extensions.cpp ]
|
||||||
[ run test_file_pool.cpp ]
|
[ run test_file_pool.cpp ]
|
||||||
[ run test_save_resume.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;
|
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
|
std::string make_ep_string(char const* address, bool const is_v6
|
||||||
, char const* port)
|
, 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)
|
// only monitor alerts for session 0 (the downloader)
|
||||||
print_alerts(*ses[0], [=](lt::session& ses, lt::alert const* a) {
|
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));
|
ta->handle.connect_peer(lt::tcp::endpoint(peer1, 6881));
|
||||||
}
|
}
|
||||||
|
@ -149,6 +153,22 @@ void* operator new(std::size_t sz)
|
||||||
{
|
{
|
||||||
char stack[10000];
|
char stack[10000];
|
||||||
print_backtrace(stack, sizeof(stack), 40, nullptr);
|
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);
|
std::printf("\n\nthrowing bad_alloc (as part of test)\n%s\n\n\n", stack);
|
||||||
throw std::bad_alloc();
|
throw std::bad_alloc();
|
||||||
}
|
}
|
||||||
|
@ -162,7 +182,7 @@ void operator delete(void* ptr) noexcept
|
||||||
|
|
||||||
TORRENT_TEST(error_handling)
|
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.
|
// 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
|
// 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);
|
std::printf("\n\n === ROUND %d ===\n\n", i);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
g_alloc_counter = 100 + i;
|
g_alloc_counter = i;
|
||||||
using namespace lt;
|
using namespace lt;
|
||||||
run_test(
|
run_test(
|
||||||
[](lt::session&, lt::alert const*) {},
|
[](lt::session&, lt::alert const*) {},
|
||||||
|
@ -211,5 +231,12 @@ TORRENT_TEST(error_handling)
|
||||||
// continue, we won't exercise any new code paths
|
// continue, we won't exercise any new code paths
|
||||||
if (g_alloc_counter > 0) break;
|
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)
|
for (int i = 0; i < blocks_in_piece; ++i)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(blocks[i].buf == nullptr);
|
|
||||||
TORRENT_ASSERT(!blocks[i].pending);
|
TORRENT_ASSERT(!blocks[i].pending);
|
||||||
TORRENT_ASSERT(blocks[i].refcount == 0);
|
TORRENT_ASSERT(blocks[i].refcount == 0);
|
||||||
TORRENT_ASSERT(blocks[i].hashing_count == 0);
|
TORRENT_ASSERT(blocks[i].hashing_count == 0);
|
||||||
|
|
|
@ -227,6 +227,9 @@ constexpr disk_job_flags_t disk_interface::cache_hit;
|
||||||
TORRENT_ASSERT(storage);
|
TORRENT_ASSERT(storage);
|
||||||
if (m_free_slots.empty())
|
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();
|
storage_index_t const idx = m_torrents.end_index();
|
||||||
m_torrents.emplace_back(std::move(storage));
|
m_torrents.emplace_back(std::move(storage));
|
||||||
m_torrents.back()->set_storage_index(idx);
|
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()
|
disk_io_thread::~disk_io_thread()
|
||||||
{
|
{
|
||||||
DLOG("destructing disk_io_thread\n");
|
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);
|
TORRENT_ASSERT(m_magic == 0x1337);
|
||||||
#if TORRENT_USE_ASSERTS
|
|
||||||
m_magic = 0xdead;
|
m_magic = 0xdead;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void disk_io_thread::abort(bool const wait)
|
void disk_io_thread::abort(bool const wait)
|
||||||
{
|
{
|
||||||
|
|
|
@ -182,6 +182,11 @@ namespace libtorrent {
|
||||||
, print_endpoint(local_ep).c_str());
|
, print_endpoint(local_ep).c_str());
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
#if TORRENT_USE_ASSERTS
|
||||||
piece_failed = false;
|
piece_failed = false;
|
||||||
m_in_constructor = false;
|
m_in_constructor = false;
|
||||||
|
@ -372,8 +377,6 @@ namespace libtorrent {
|
||||||
// if this is an incoming connection, we're done here
|
// if this is an incoming connection, we're done here
|
||||||
if (!m_connecting) return;
|
if (!m_connecting) return;
|
||||||
|
|
||||||
if (m_connecting && t) t->inc_num_connecting(m_peer_info);
|
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_LOGGING
|
#ifndef TORRENT_DISABLE_LOGGING
|
||||||
if (should_log(peer_log_alert::outgoing))
|
if (should_log(peer_log_alert::outgoing))
|
||||||
{
|
{
|
||||||
|
@ -529,14 +532,14 @@ namespace libtorrent {
|
||||||
}
|
}
|
||||||
|
|
||||||
void peer_connection::peer_log(peer_log_alert::direction_t direction
|
void peer_connection::peer_log(peer_log_alert::direction_t direction
|
||||||
, char const* event) const
|
, char const* event) const noexcept
|
||||||
{
|
{
|
||||||
peer_log(direction, event, "");
|
peer_log(direction, event, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
TORRENT_FORMAT(4,5)
|
TORRENT_FORMAT(4,5)
|
||||||
void peer_connection::peer_log(peer_log_alert::direction_t direction
|
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());
|
TORRENT_ASSERT(is_single_thread());
|
||||||
|
|
||||||
|
@ -555,6 +558,7 @@ namespace libtorrent {
|
||||||
va_end(v);
|
va_end(v);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
catch (std::exception const&) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||||
|
@ -797,8 +801,6 @@ namespace libtorrent {
|
||||||
|
|
||||||
// INVARIANT_CHECK;
|
// INVARIANT_CHECK;
|
||||||
TORRENT_ASSERT(!m_in_constructor);
|
TORRENT_ASSERT(!m_in_constructor);
|
||||||
TORRENT_ASSERT(m_disconnecting);
|
|
||||||
TORRENT_ASSERT(m_disconnect_started);
|
|
||||||
TORRENT_ASSERT(!m_destructed);
|
TORRENT_ASSERT(!m_destructed);
|
||||||
#if TORRENT_USE_ASSERTS
|
#if TORRENT_USE_ASSERTS
|
||||||
m_destructed = true;
|
m_destructed = true;
|
||||||
|
@ -836,7 +838,6 @@ namespace libtorrent {
|
||||||
TORRENT_ASSERT(t || !m_connecting);
|
TORRENT_ASSERT(t || !m_connecting);
|
||||||
|
|
||||||
// we should really have dealt with this already
|
// we should really have dealt with this already
|
||||||
TORRENT_ASSERT(!m_connecting);
|
|
||||||
if (m_connecting)
|
if (m_connecting)
|
||||||
{
|
{
|
||||||
m_counters.inc_stats_counter(counters::num_peers_half_open, -1);
|
m_counters.inc_stats_counter(counters::num_peers_half_open, -1);
|
||||||
|
@ -853,11 +854,6 @@ namespace libtorrent {
|
||||||
#endif
|
#endif
|
||||||
TORRENT_ASSERT(m_request_queue.empty());
|
TORRENT_ASSERT(m_request_queue.empty());
|
||||||
TORRENT_ASSERT(m_download_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
|
bool peer_connection::on_parole() const
|
||||||
|
@ -4385,7 +4381,7 @@ namespace libtorrent {
|
||||||
m_queued_time_critical = 0;
|
m_queued_time_critical = 0;
|
||||||
|
|
||||||
#if TORRENT_USE_INVARIANT_CHECKS
|
#if TORRENT_USE_INVARIANT_CHECKS
|
||||||
check_invariant();
|
try { check_invariant(); } catch (std::exception const&) {}
|
||||||
#endif
|
#endif
|
||||||
t->remove_peer(self());
|
t->remove_peer(self());
|
||||||
|
|
||||||
|
@ -6326,10 +6322,6 @@ namespace libtorrent {
|
||||||
TORRENT_ASSERT(m_request_queue.empty());
|
TORRENT_ASSERT(m_request_queue.empty());
|
||||||
TORRENT_ASSERT(m_disconnect_started);
|
TORRENT_ASSERT(m_disconnect_started);
|
||||||
}
|
}
|
||||||
else if (!m_in_constructor)
|
|
||||||
{
|
|
||||||
TORRENT_ASSERT(m_ses.has_peer(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
TORRENT_ASSERT(m_outstanding_bytes >= 0);
|
TORRENT_ASSERT(m_outstanding_bytes >= 0);
|
||||||
if (t && t->valid_metadata() && !m_disconnecting)
|
if (t && t->valid_metadata() && !m_disconnecting)
|
||||||
|
|
|
@ -882,12 +882,13 @@ namespace aux {
|
||||||
session_log(" aborting all connections (%d)", int(m_connections.size()));
|
session_log(" aborting all connections (%d)", int(m_connections.size()));
|
||||||
#endif
|
#endif
|
||||||
// abort all connections
|
// abort all connections
|
||||||
// keep in mind that connections that are not associated with a torrent
|
for (connection_map::iterator i = m_connections.begin();
|
||||||
// will remove its entry from m_connections immediately, which means we
|
i != m_connections.end();)
|
||||||
// can't iterate over it here
|
{
|
||||||
auto conns = m_connections;
|
peer_connection* p = (*i).get();
|
||||||
for (auto const& p : conns)
|
++i;
|
||||||
p->disconnect(errors::stopping_torrent, operation_t::bittorrent);
|
p->disconnect(errors::stopping_torrent, operation_t::bittorrent);
|
||||||
|
}
|
||||||
|
|
||||||
// close the listen sockets
|
// close the listen sockets
|
||||||
for (auto const& l : m_listen_sockets)
|
for (auto const& l : m_listen_sockets)
|
||||||
|
@ -4533,7 +4534,7 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
TORRENT_FORMAT(2,3)
|
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;
|
if (!m_alerts.should_post<log_alert>()) return;
|
||||||
|
|
||||||
|
@ -4542,6 +4543,7 @@ namespace {
|
||||||
m_alerts.emplace_alert<log_alert>(fmt, v);
|
m_alerts.emplace_alert<log_alert>(fmt, v);
|
||||||
va_end(v);
|
va_end(v);
|
||||||
}
|
}
|
||||||
|
catch (std::exception const&) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void session_impl::get_torrent_status(std::vector<torrent_status>* ret
|
void session_impl::get_torrent_status(std::vector<torrent_status>* ret
|
||||||
|
@ -7147,7 +7149,7 @@ namespace {
|
||||||
return m_ses.alerts().should_post<log_alert>();
|
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;
|
if (!m_ses.alerts().should_post<log_alert>()) return;
|
||||||
|
|
||||||
|
@ -7156,5 +7158,6 @@ namespace {
|
||||||
m_ses.alerts().emplace_alert<log_alert>(fmt, v);
|
m_ses.alerts().emplace_alert<log_alert>(fmt, v);
|
||||||
va_end(v);
|
va_end(v);
|
||||||
}
|
}
|
||||||
|
catch (std::exception const&) {}
|
||||||
#endif // TORRENT_DISABLE_LOGGING
|
#endif // TORRENT_DISABLE_LOGGING
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -4361,8 +4361,23 @@ namespace libtorrent {
|
||||||
// the torrent object from there
|
// the torrent object from there
|
||||||
if (m_storage)
|
if (m_storage)
|
||||||
{
|
{
|
||||||
m_ses.disk_thread().async_stop_torrent(m_storage
|
try {
|
||||||
, std::bind(&torrent::on_torrent_aborted, shared_from_this()));
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -4401,6 +4416,10 @@ namespace libtorrent {
|
||||||
// have been destructed
|
// have been destructed
|
||||||
if (m_peer_list) m_peer_list->clear();
|
if (m_peer_list) m_peer_list->clear();
|
||||||
m_connections.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)
|
void torrent::set_super_seeding(bool on)
|
||||||
|
@ -6877,22 +6896,7 @@ namespace libtorrent {
|
||||||
peers_erased(st.erased);
|
peers_erased(st.erased);
|
||||||
|
|
||||||
m_peers_to_disconnect.reserve(m_connections.size() + 1);
|
m_peers_to_disconnect.reserve(m_connections.size() + 1);
|
||||||
|
m_connections.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
|
|
||||||
|
|
||||||
#if TORRENT_USE_ASSERTS
|
#if TORRENT_USE_ASSERTS
|
||||||
error_code ec;
|
error_code ec;
|
||||||
|
@ -6956,13 +6960,33 @@ namespace libtorrent {
|
||||||
if (m_share_mode)
|
if (m_share_mode)
|
||||||
recalc_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
|
#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"
|
debug_log("ATTACHED CONNECTION \"%s\" connections: %d limit: %d"
|
||||||
, print_endpoint(p->remote()).c_str(), num_peers()
|
, print_endpoint(p->remote()).c_str(), num_peers()
|
||||||
, m_max_connections);
|
, m_max_connections);
|
||||||
}
|
}
|
||||||
|
catch (std::exception const&) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -7775,7 +7799,7 @@ namespace libtorrent {
|
||||||
|
|
||||||
TORRENT_ASSERT(is_single_thread());
|
TORRENT_ASSERT(is_single_thread());
|
||||||
// this fires during disconnecting peers
|
// 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 seeds = 0;
|
||||||
int num_uploads = 0;
|
int num_uploads = 0;
|
||||||
|
@ -7784,10 +7808,6 @@ namespace libtorrent {
|
||||||
std::map<piece_block, int> num_requests;
|
std::map<piece_block, int> num_requests;
|
||||||
for (peer_connection const* peer : *this)
|
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;
|
peer_connection const& p = *peer;
|
||||||
|
|
||||||
if (p.is_connecting()) ++num_connecting;
|
if (p.is_connecting()) ++num_connecting;
|
||||||
|
@ -7813,16 +7833,19 @@ namespace libtorrent {
|
||||||
if (associated_torrent != this && associated_torrent != nullptr)
|
if (associated_torrent != this && associated_torrent != nullptr)
|
||||||
TORRENT_ASSERT_FAIL();
|
TORRENT_ASSERT_FAIL();
|
||||||
}
|
}
|
||||||
TORRENT_ASSERT(num_uploads == int(m_num_uploads));
|
TORRENT_ASSERT_VAL(num_uploads == int(m_num_uploads), int(m_num_uploads) - num_uploads);
|
||||||
TORRENT_ASSERT(seeds == int(m_num_seeds));
|
TORRENT_ASSERT_VAL(seeds == int(m_num_seeds), int(m_num_seeds) - seeds);
|
||||||
TORRENT_ASSERT(num_connecting == int(m_num_connecting));
|
TORRENT_ASSERT_VAL(num_connecting == int(m_num_connecting), int(m_num_connecting) - num_connecting);
|
||||||
TORRENT_ASSERT(num_connecting_seeds == int(m_num_connecting_seeds));
|
TORRENT_ASSERT_VAL(num_connecting_seeds == int(m_num_connecting_seeds)
|
||||||
TORRENT_ASSERT(int(m_num_uploads) <= num_peers());
|
, int(m_num_connecting_seeds) - num_connecting_seeds);
|
||||||
TORRENT_ASSERT(int(m_num_seeds) <= num_peers());
|
TORRENT_ASSERT_VAL(int(m_num_uploads) <= num_peers(), m_num_uploads - num_peers());
|
||||||
TORRENT_ASSERT(int(m_num_connecting) <= num_peers());
|
TORRENT_ASSERT_VAL(int(m_num_seeds) <= num_peers(), m_num_seeds - num_peers());
|
||||||
TORRENT_ASSERT(int(m_num_connecting_seeds) <= num_peers());
|
TORRENT_ASSERT_VAL(int(m_num_connecting) <= num_peers(), int(m_num_connecting) - num_peers());
|
||||||
TORRENT_ASSERT(int(m_num_connecting) + int(m_num_seeds) >= int(m_num_connecting_seeds));
|
TORRENT_ASSERT_VAL(int(m_num_connecting_seeds) <= num_peers(), int(m_num_connecting_seeds) - num_peers());
|
||||||
TORRENT_ASSERT(int(m_num_connecting) + int(m_num_seeds) - 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())
|
if (has_picker())
|
||||||
{
|
{
|
||||||
|
@ -10979,7 +11002,7 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
TORRENT_FORMAT(2,3)
|
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;
|
if (!alerts().should_post<torrent_log_alert>()) return;
|
||||||
|
|
||||||
|
@ -10989,6 +11012,7 @@ namespace {
|
||||||
const_cast<torrent*>(this)->get_handle(), fmt, v);
|
const_cast<torrent*>(this)->get_handle(), fmt, v);
|
||||||
va_end(v);
|
va_end(v);
|
||||||
}
|
}
|
||||||
|
catch (std::exception const&) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,11 +70,11 @@ struct mock_peer_connection
|
||||||
virtual ~mock_peer_connection() = default;
|
virtual ~mock_peer_connection() = default;
|
||||||
|
|
||||||
#if !defined TORRENT_DISABLE_LOGGING
|
#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; }
|
{ return true; }
|
||||||
|
|
||||||
void peer_log(peer_log_alert::direction_t dir, char const* event
|
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_list v;
|
||||||
va_start(v, fmt);
|
va_start(v, fmt);
|
||||||
|
|
Loading…
Reference in New Issue